예제 #1
0
        private static IEnumerable <TValue> InOrder(RbtNode <TKey, TValue> n)
        {
            if (n == Nil)
            {
                yield break;
            }

            if (n.Left != Nil)
            {
                foreach (var x in InOrder(n.Left))
                {
                    yield return(x);
                }
            }

            yield return(n.Value);

            if (n.Right != Nil)
            {
                foreach (var x in InOrder(n.Right))
                {
                    yield return(x);
                }
            }
        }
예제 #2
0
        private void RightRotate(RbtNode <TKey, TValue> node)
        {
            if (node.Left == Nil)
            {
                return;
            }

            var y = node.Left;

            node.Left = y.Right;

            if (y.Right != Nil)
            {
                y.Right.Parent = node;
            }

            y.Parent = node.Parent;
            if (node.Parent == Nil)
            {
                _root = y;
            }
            else if (node == node.Parent.Left)
            {
                node.Parent.Left = y;
            }
            else
            {
                node.Parent.Right = y;
            }

            y.Right     = node;
            node.Parent = y;
        }
예제 #3
0
        private void InsertFixup(RbtNode <TKey, TValue> node)
        {
            while (node.Parent.IsRed)
            {
                if (node.Parent == node.Parent.Parent.Left)
                {
                    var aunt = node.Parent.Parent.Right;
                    if (aunt.IsRed)
                    {
                        node.Parent.MarkBlack();
                        aunt.MarkBlack();
                        node.Parent.Parent.MarkRed();

                        node = node.Parent.Parent;
                    }
                    else
                    {
                        if (node == node.Parent.Right)
                        {
                            node = node.Parent;
                            LeftRotate(node);
                        }

                        node.Parent.MarkBlack();
                        node.Parent.Parent.MarkRed();
                        RightRotate(node.Parent.Parent);
                    }
                }
                else
                {
                    var aunt = node.Parent.Parent.Left;
                    if (aunt.IsRed)
                    {
                        node.Parent.MarkBlack();
                        aunt.MarkBlack();
                        node.Parent.Parent.MarkRed();

                        node = node.Parent.Parent;
                    }
                    else
                    {
                        if (node == node.Parent.Left)
                        {
                            node = node.Parent;
                            RightRotate(node);
                        }

                        node.Parent.MarkBlack();
                        node.Parent.Parent.MarkRed();
                        LeftRotate(node.Parent.Parent);
                    }
                }
            }

            _root.MarkBlack();
        }
예제 #4
0
        private RbtNode <TKey, TValue> MinOf(RbtNode <TKey, TValue> node)
        {
            var result = node;
            var x      = node;

            while (x != Nil)
            {
                result = x;
                x      = x.Left;
            }
            return(result == Nil ? null : result);
        }
예제 #5
0
        private void Transplant(RbtNode <TKey, TValue> source, RbtNode <TKey, TValue> dest)
        {
            if (source.Parent == Nil)
            {
                _root = dest;
            }
            else if (source == source.Parent.Left)
            {
                source.Parent.Left = dest;
            }
            else
            {
                source.Parent.Right = dest;
            }

            dest.Parent = source.Parent;
        }
예제 #6
0
        public void Delete(RbtNode <TKey, TValue> node)
        {
            var y          = node;
            var yOrigColor = node.IsRed;
            RbtNode <TKey, TValue> x;

            if (node.Left == Nil)
            {
                x = node.Right;
                Transplant(node, node.Right);
            }
            else if (node.Right == Nil)
            {
                x = node.Left;
                Transplant(node, node.Left);
            }
            else
            {
                y          = MinOf(node.Right);
                yOrigColor = y.IsRed;
                x          = y.Right;

                if (y.Parent == node)
                {
                    x.Parent = y;
                }
                else
                {
                    Transplant(y, y.Right);
                    y.Right        = node.Right;
                    y.Right.Parent = y;
                }

                Transplant(node, y);
                y.Left        = node.Left;
                y.Left.Parent = y;
                y.IsRed       = node.IsRed;
            }

            if (!yOrigColor) // if is black
            {
                DeleteFixup(x);
            }
        }
예제 #7
0
        public RbtNode <TKey, TValue> Insert(TKey key, TValue value)
        {
            var node   = new RbtNode <TKey, TValue>(key, value);
            var parent = Nil;
            var x      = _root;

            while (x != Nil)
            {
                parent = x;

                var keyComparision = _keyComparer.Compare(node.Key, x.Key);
                if (keyComparision < 0)
                {
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            node.Parent = parent;

            if (parent == Nil)
            {
                _root = node;
            }
            else if (_keyComparer.Compare(node.Key, parent.Key) < 0)
            {
                parent.Left = node;
            }
            else
            {
                parent.Right = node;
            }

            InsertFixup(node);
            return(node);
        }
예제 #8
0
 private void DeleteFixup(RbtNode <TKey, TValue> node)
 {
     while (node != _root && node.IsBlack)
     {
         if (node == node.Parent.Left)
         {
             var brother = node.Parent.Right;
             if (brother.IsRed)
             {
                 brother.MarkBlack();
                 node.Parent.MarkRed();
                 LeftRotate(node.Parent);
                 brother = node.Parent.Right;
             }
             if (brother.Left.IsBlack && brother.Right.IsBlack)
             {
                 brother.MarkRed();
                 node = node.Parent;
             }
             else
             {
                 if (brother.Right.IsBlack)
                 {
                     brother.Left.MarkBlack();
                     brother.MarkRed();
                     RightRotate(brother);
                     brother = node.Parent.Right;
                 }
                 brother.IsRed = node.Parent.IsRed;
                 node.Parent.MarkBlack();
                 brother.Right.MarkBlack();
                 LeftRotate(node.Parent);
                 node = _root;
             }
         }
         else
         {
             var brother = node.Parent.Left;
             if (brother.IsRed)
             {
                 brother.MarkBlack();
                 node.Parent.MarkRed();
                 RightRotate(node.Parent);
                 brother = node.Parent.Left;
             }
             if (brother.Right.IsBlack && brother.Left.IsBlack)
             {
                 brother.MarkRed();
                 node = node.Parent;
             }
             else
             {
                 if (brother.Left.IsBlack)
                 {
                     brother.Right.MarkBlack();
                     brother.MarkRed();
                     LeftRotate(brother);
                     brother = node.Parent.Left;
                 }
                 brother.IsRed = node.Parent.IsRed;
                 node.Parent.MarkBlack();
                 brother.Left.MarkBlack();
                 RightRotate(node.Parent);
                 node = _root;
             }
         }
     }
 }
예제 #9
0
 public RbtNode(TKey key, TValue value, RbtNode <TKey, TValue> parent)
     : this(key, value)
 {
     Parent = parent;
 }