Example #1
0
        public void Insert(T value)
        {
            var previous = RbtNode <T> .Nil;
            var current  = Head;

            while (current != RbtNode <T> .Nil)
            {
                previous = current;
                current  = current.Value.CompareTo(value) > 0 ? current.Left : current.Right;
            }
            var newNode = new RbtNode <T>(value, previous, false);

            if (previous == RbtNode <T> .Nil)
            {
                Head = newNode;
            }
            else if (previous.Value.CompareTo(value) > 0)
            {
                previous.Left = newNode;
            }
            else
            {
                previous.Right = newNode;
            }
            InsertFixup(newNode);
        }
Example #2
0
        public void Remove(T item)
        {
            var node = FindNode(item);

            if (node == RbtNode <T> .Nil)
            {
                return;
            }
            var tmp  = node.Left == RbtNode <T> .Nil || node.Right == RbtNode <T> .Nil ? node : GetNextNode(node);
            var tmp2 = tmp.Left != RbtNode <T> .Nil ? tmp.Left : tmp.Right;

            tmp2.Parent = tmp.Parent;
            if (tmp.Parent == RbtNode <T> .Nil)
            {
                Head = tmp2;
            }
            else if (tmp == tmp.Parent.Left)
            {
                tmp.Parent.Left = tmp2;
            }
            else
            {
                tmp.Parent.Right = tmp2;
            }
            if (tmp != node)
            {
                node.Value = tmp.Value;
            }
            if (tmp.IsBlack)
            {
                RemoveFixUp(tmp);
            }
        }
Example #3
0
 public RbtNode(T value, RbtNode <T> parent, bool isBlack)
 {
     Value   = value;
     Parent  = parent ?? Nil;
     Left    = Right = Nil;
     IsBlack = isBlack;
 }
Example #4
0
 private void InsertFixup(RbtNode <T> node)
 {
     while (!node.Parent.IsBlack)
     {
         node = node.Parent == node.Parent.Parent.Left ? InsertLeftFixup(node) : InsertRightFixUp(node);
     }
     Head.IsBlack = true;
 }
Example #5
0
        private static RbtNode <T> GetMaxNodeOrThrow(RbtNode <T> node)
        {
            if (node == RbtNode <T> .Nil)
            {
                throw new Exception("Tree is empty");
            }
            var current = node;

            while (current.Right != RbtNode <T> .Nil)
            {
                current = current.Right;
            }
            return(current);
        }
Example #6
0
        private static RbtNode <T> GetNextNode(RbtNode <T> node)
        {
            if (node.Right != RbtNode <T> .Nil)
            {
                return(GetMinNodeOrThrow(node.Right));
            }
            var tmp = node.Parent;

            while (tmp != RbtNode <T> .Nil && node == tmp.Right)
            {
                node = tmp;
                tmp  = tmp.Parent;
            }
            return(tmp);
        }
Example #7
0
 private void FixParent(RbtNode <T> lastNode, RbtNode <T> newNode)
 {
     if (lastNode.Parent == RbtNode <T> .Nil)
     {
         Head = newNode;
     }
     else if (lastNode == lastNode.Parent.Left)
     {
         lastNode.Parent.Left = newNode;
     }
     else
     {
         lastNode.Parent.Right = newNode;
     }
 }
Example #8
0
        public void RotateToRight(RbtNode <T> node)
        {
            var tmp = node.Left;

            if (tmp == RbtNode <T> .Nil)
            {
                return;
            }
            node.Left = tmp.Right;
            tmp.Right = node;
            if (node.Left != RbtNode <T> .Nil)
            {
                node.Left.Parent = node;
            }
            FixParent(node, tmp);
            tmp.Parent  = node.Parent;
            node.Parent = tmp;
        }
Example #9
0
        public void RotateToLeft(RbtNode <T> node)
        {
            var tmp = node.Right;

            if (tmp == RbtNode <T> .Nil || tmp.Value.CompareTo(node.Value) == 0)
            {
                return;
            }
            node.Right = tmp.Left;
            tmp.Left   = node;
            if (node.Right != RbtNode <T> .Nil)
            {
                node.Right.Parent = node;
            }
            FixParent(node, tmp);
            tmp.Parent  = node.Parent;
            node.Parent = tmp;
        }
Example #10
0
        private RbtNode <T> InsertRightFixUp(RbtNode <T> node)
        {
            var tmp = node.Parent.Parent.Left;

            if (!tmp.IsBlack)
            {
                node.Parent.IsBlack        = true;
                tmp.IsBlack                = true;
                node.Parent.Parent.IsBlack = false;
                return(node.Parent.Parent);
            }
            if (node == node.Parent.Left)
            {
                RotateToRight(node = node.Parent);
            }
            node.Parent.IsBlack        = true;
            node.Parent.Parent.IsBlack = false;
            RotateToLeft(node.Parent.Parent);
            return(node);
        }
Example #11
0
 //TODO: декомпозиция рефакторинг и все такое
 private void RemoveFixUp(RbtNode <T> node)
 {
     while (node != Head && node.IsBlack)
     {
         if (node == node.Parent.Left)
         {
             var tmp = node.Parent.Right;
             if (!tmp.IsBlack)
             {
                 tmp.IsBlack         = true;
                 node.Parent.IsBlack = false;
                 RotateToLeft(node.Parent);
                 tmp = node.Parent.Right;
             }
             if (tmp.Left.IsBlack && tmp.Right.IsBlack)
             {
                 tmp.IsBlack = false;
                 node        = node.Parent;
             }
             else
             {
                 if (tmp.Right.IsBlack)
                 {
                     tmp.Left.IsBlack = true;
                     tmp.IsBlack      = false;
                     RotateToRight(tmp);
                     tmp = node.Parent.Right;
                 }
                 tmp.IsBlack         = node.Parent.IsBlack;
                 node.Parent.IsBlack = true;
                 tmp.Right.IsBlack   = true;
                 RotateToLeft(node.Parent);
                 node = Head;
             }
         }
         else
         {
             var tmp = node.Parent.Left;
             if (!tmp.IsBlack)
             {
                 tmp.IsBlack         = true;
                 node.Parent.IsBlack = false;
                 RotateToRight(node.Parent);
                 tmp = node.Parent.Left;
             }
             if (tmp.Left.IsBlack && tmp.Right.IsBlack)
             {
                 tmp.IsBlack = false;
                 node        = node.Parent;
             }
             else
             {
                 if (tmp.Left.IsBlack)
                 {
                     tmp.Right.IsBlack = true;
                     tmp.IsBlack       = false;
                     RotateToLeft(tmp);
                     tmp = node.Parent.Left;
                 }
                 tmp.IsBlack         = node.Parent.IsBlack;
                 node.Parent.IsBlack = true;
                 tmp.Left.IsBlack    = true;
                 RotateToRight(node.Parent);
                 node = Head;
             }
         }
     }
 }