예제 #1
0
        private void CaseSixRotationDelete(MyRedBlackTreeNode <T> node)
        {
            var sibling = GetSibling(node);

            if (node.IsDoubleBlack && sibling != null &&
                sibling.Color == RedBlackTreeNodeColor.Black)
            {
                bool isRotated = false;
                if (sibling?.Right?.Color == RedBlackTreeNodeColor.Red && sibling.Left != null &&
                    sibling.Parent.Right == sibling)
                {
                    RightRightRotation(sibling.Right);
                    isRotated           = true;
                    sibling.Right.Color = RedBlackTreeNodeColor.Black;
                }
                else if (sibling?.Left?.Color == RedBlackTreeNodeColor.Red && sibling.Right != null &&
                         sibling.Parent.Left == sibling)
                {
                    LeftLeftRotation(sibling.Left);
                    isRotated          = true;
                    sibling.Left.Color = RedBlackTreeNodeColor.Black;
                }

                if (isRotated)
                {
                    sibling.Color      = node.Parent.Color;
                    node.Parent.Color  = RedBlackTreeNodeColor.Black;
                    node.IsDoubleBlack = false;
                }
            }
        }
예제 #2
0
        private void LeftLeftRotation(MyRedBlackTreeNode <T> root)
        {
            var parentParent = root.Parent.Parent;

            if (parentParent.Parent != null)
            {
                if (parentParent.Parent.Left == parentParent)
                {
                    parentParent.Parent.Left = root.Parent;
                }
                else
                {
                    parentParent.Parent.Right = root.Parent;
                }
                root.Parent.Parent = parentParent.Parent;
            }
            else
            {
                Root = root.Parent;
                root.Parent.Parent = null;
            }

            parentParent.Left        = root.Parent.Right;
            parentParent.Left.Parent = parentParent;
            root.Parent.Right        = parentParent;
            parentParent.Parent      = root.Parent;
            if (parentParent == Root)
            {
                Root = root.Parent;
            }
        }
예제 #3
0
        private void CaseFiveRotationDelete(MyRedBlackTreeNode <T> node)
        {
            var sibling = GetSibling(node);

            if (node.IsDoubleBlack && sibling != null &&
                sibling.Color == RedBlackTreeNodeColor.Black)
            {
                if (sibling.Parent?.Right == sibling &&
                    sibling.Left?.Color == RedBlackTreeNodeColor.Red &&
                    sibling.Right?.Color == RedBlackTreeNodeColor.Black)
                {
                    RightLeftRotation(sibling.Left);
                    sibling.Color        = RedBlackTreeNodeColor.Red;
                    sibling.Parent.Color = RedBlackTreeNodeColor.Black;
                }
                else if (sibling.Parent?.Left == sibling &&
                         sibling.Right?.Color == RedBlackTreeNodeColor.Red &&
                         sibling.Left?.Color == RedBlackTreeNodeColor.Black)
                {
                    LeftRightRotation(sibling.Right);
                    sibling.Color        = RedBlackTreeNodeColor.Red;
                    sibling.Parent.Color = RedBlackTreeNodeColor.Black;
                }
            }
            CaseSixRotationDelete(node);
        }
예제 #4
0
        private void RemoveDoubleBlack(MyRedBlackTreeNode <T> node)
        {
            Count--;
            if (node == Root)
            {
                Root = null;
                return;
            }

            var isRight = node.Parent.Right == node;

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

            node.Right.Parent        = node.Parent;
            node.Right.IsDoubleBlack = true;

            CaseOneRotationDelete(node.Right);
            node.Right  = null;
            node.Parent = null;
        }
예제 #5
0
 public MyRedBlackTreeNode(T data)
 {
     Data  = data;
     Color = RedBlackTreeNodeColor.Red;
     Left  = new MyRedBlackTreeNode <T>(true, this);
     Right = new MyRedBlackTreeNode <T>(true, this);
 }
예제 #6
0
        private void RemoveBlackWithSingleRedChild(MyRedBlackTreeNode <T> node, bool isSingleLeft)
        {
            if (Root == node)
            {
                Root        = isSingleLeft ? node.Left : node.Right;
                Root.Color  = RedBlackTreeNodeColor.Black;
                Root.Parent = null;
            }
            else
            {
                if (node.Parent.Right == node)
                {
                    node.Parent.Right = isSingleLeft ? node.Left : node.Right;
                }
                else
                {
                    node.Parent.Left = isSingleLeft ? node.Left : node.Right;
                }

                if (isSingleLeft)
                {
                    node.Left.Parent = node.Parent;
                    node.Left.Color  = RedBlackTreeNodeColor.Black;
                }
                else
                {
                    node.Right.Parent = node.Parent;
                    node.Right.Color  = RedBlackTreeNodeColor.Black;
                }

                node.Parent = null;
                node.Right  = null;
            }
            Count--;
        }
예제 #7
0
        public void Remove(MyRedBlackTreeNode <T> node)
        {
            if (node == null)
            {
                throw new ArgumentNullException();
            }

            bool isSingleLeft  = node.Left.Color == RedBlackTreeNodeColor.Red && node.Right.IsNull;
            bool isSingleRight = node.Right.Color == RedBlackTreeNodeColor.Red && node.Left.IsNull;

            if (!node.Left.IsNull && !node.Right.IsNull)
            {
                var successor = FindInOrderSuccessor(node);
                SwapWithSuccessor(node, successor);
                Remove(node);
            }
            else if (node.Color == RedBlackTreeNodeColor.Red)
            {
                RemoveSingleRed(node);
            }
            else if (node.Color == RedBlackTreeNodeColor.Black &&
                     (isSingleLeft || isSingleRight))
            {
                RemoveBlackWithSingleRedChild(node, isSingleLeft);
            }
            else
            {
                RemoveDoubleBlack(node);
            }
        }
예제 #8
0
 public MyRedBlackTreeNode(T data,
                           RedBlackTreeNodeColor color,
                           MyRedBlackTreeNode <T> left,
                           MyRedBlackTreeNode <T> right) : this(data, color)
 {
     Left  = left;
     Right = right;
 }
예제 #9
0
 public MyRedBlackTreeNode(T data,
                           RedBlackTreeNodeColor color,
                           MyRedBlackTreeNode <T> left,
                           MyRedBlackTreeNode <T> right,
                           MyRedBlackTreeNode <T> parent) : this(data, color, left, right)
 {
     Parent = parent;
 }
예제 #10
0
        private void SwapWithSuccessor(MyRedBlackTreeNode <T> node, MyRedBlackTreeNode <T> successor)
        {
            var parentNode = node.Parent;

            if (parentNode != null)
            {
                if (parentNode.Left == node)
                {
                    parentNode.Left = successor;
                }
                else
                {
                    parentNode.Right = successor;
                }
            }

            var parentSuccessor = successor.Parent;

            if (parentSuccessor.Left == successor)
            {
                parentSuccessor.Left = node;
            }
            else
            {
                parentSuccessor.Right = node;
            }

            successor.Parent = parentNode;
            node.Parent      = parentSuccessor;

            var nodeLeft = node.Left;

            node.Left             = successor.Left;
            successor.Left        = nodeLeft;
            node.Left.Parent      = node;
            successor.Left.Parent = successor;

            var nodeRight = node.Right;

            node.Right             = successor.Right;
            successor.Right        = nodeRight;
            node.Right.Parent      = node;
            successor.Right.Parent = successor;

            var color = node.Color;

            node.Color      = successor.Color;
            successor.Color = color;

            if (Root == node)
            {
                Root = successor;
            }
        }
예제 #11
0
        private MyRedBlackTreeNode <T> FindInOrderSuccessor(MyRedBlackTreeNode <T> root)
        {
            var next = root.Right;

            while (!next.IsNull && !next.Left.IsNull)
            {
                next = next.Left;
            }

            return(next);
        }
예제 #12
0
 private void CaseOneRotationDelete(MyRedBlackTreeNode <T> node)
 {
     if (node == Root && node.IsDoubleBlack)
     {
         node.Color         = RedBlackTreeNodeColor.Black;
         node.IsDoubleBlack = false;
     }
     else
     {
         CaseTwoRotationDelete(node);
     }
 }
예제 #13
0
 private MyRedBlackTreeNode <T> GetSibling(MyRedBlackTreeNode <T> node)
 {
     if (node == null || node.Parent == null)
     {
         return(null);
     }
     if (node.Parent.Left == node)
     {
         return(node.Parent.Right);
     }
     return(node.Parent.Left);
 }
예제 #14
0
 public void Insert(T data)
 {
     if (Root == null)
     {
         Root = new MyRedBlackTreeNode <T>(data, RedBlackTreeNodeColor.Black);
     }
     else
     {
         InsertHelper(Root, data);
     }
     Count++;
 }
예제 #15
0
        private void LeftRightRotation(MyRedBlackTreeNode <T> root)
        {
            var parentParent = root.Parent.Parent;

            var left = root.Left;

            root.Left              = root.Parent;
            parentParent.Left      = root;
            root.Left.Right        = left;
            root.Parent            = parentParent;
            root.Left.Parent       = root;
            root.Left.Right.Parent = root.Left;
        }
예제 #16
0
        private void RemoveSingleRed(MyRedBlackTreeNode <T> node)
        {
            if (node.Parent.Left == node)
            {
                node.Parent.Left = node.Right;
            }
            else
            {
                node.Parent.Right = node.Right;
            }
            node.Right.Parent = node.Parent;

            node.Right  = null;
            node.Parent = null;
            Count--;
        }
예제 #17
0
        private void CaseThreeRotationDelete(MyRedBlackTreeNode <T> node)
        {
            var sibling = GetSibling(node);

            if (node.IsDoubleBlack && sibling != null &&
                node.Parent?.Color == RedBlackTreeNodeColor.Black && sibling.Color == RedBlackTreeNodeColor.Black &&
                sibling.Left?.Color == RedBlackTreeNodeColor.Black && sibling.Right?.Color == RedBlackTreeNodeColor.Black)
            {
                node.IsDoubleBlack        = false;
                node.Parent.IsDoubleBlack = true;
                sibling.Color             = RedBlackTreeNodeColor.Red;

                CaseOneRotationDelete(node.Parent);
            }
            CaseFourRotationDelete(node);
        }
예제 #18
0
        private void CaseFourRotationDelete(MyRedBlackTreeNode <T> node)
        {
            var sibling = GetSibling(node);

            if (node.IsDoubleBlack && sibling != null &&
                node.Parent.Color == RedBlackTreeNodeColor.Red && sibling.Color == RedBlackTreeNodeColor.Black &&
                sibling.Left.Color == RedBlackTreeNodeColor.Black && sibling.Right.Color == RedBlackTreeNodeColor.Black)
            {
                node.IsDoubleBlack = false;
                node.Parent.Color  = RedBlackTreeNodeColor.Black;
                sibling.Color      = RedBlackTreeNodeColor.Red;
            }
            else
            {
                CaseFiveRotationDelete(node);
            }
        }
예제 #19
0
        private MyRedBlackTreeNode <T> FindHelper(T data, MyRedBlackTreeNode <T> root)
        {
            if (root.IsNull)
            {
                return(null);
            }

            var compared = data.CompareTo(root.Data);

            if (compared == 0 && !root.IsNull)
            {
                return(root);
            }
            if (compared < 0)
            {
                return(FindHelper(data, root.Left));
            }

            return(FindHelper(data, root.Right));
        }
예제 #20
0
        private void CaseTwoRotationDelete(MyRedBlackTreeNode <T> node)
        {
            var sibling = GetSibling(node);

            if (node.IsDoubleBlack && sibling != null &&
                node.Parent.Color == RedBlackTreeNodeColor.Black && sibling.Color == RedBlackTreeNodeColor.Red &&
                sibling.Left?.Color == RedBlackTreeNodeColor.Black && sibling.Right?.Color == RedBlackTreeNodeColor.Black)
            {
                if (node.Parent.Left == node)
                {
                    RightRightRotation(sibling.Right);
                }
                else
                {
                    LeftLeftRotation(sibling.Left);
                }
                sibling.Color     = RedBlackTreeNodeColor.Black;
                node.Parent.Color = RedBlackTreeNodeColor.Red;
            }
            CaseThreeRotationDelete(node);
        }
예제 #21
0
        private bool IsValidHelper(MyRedBlackTreeNode <T> root,
                                   MyRedBlackTreeNode <T> parent,
                                   List <int> countBlacks, int currentCount)
        {
            if (root == null || root.Parent != parent)
            {
                return(false);
            }
            if (parent != null && parent.Left != root && parent?.Right != root)
            {
                return(false);
            }
            if (parent?.Color == RedBlackTreeNodeColor.Red &&
                root.Color == RedBlackTreeNodeColor.Red)
            {
                return(false);
            }

            if (root.IsNull)
            {
                countBlacks.Add(currentCount);

                return(true);
            }

            if (root.Color == RedBlackTreeNodeColor.Black)
            {
                currentCount++;
            }
            if (!IsValidHelper(root.Left, root, countBlacks, currentCount))
            {
                return(false);
            }
            if (!IsValidHelper(root.Right, root, countBlacks, currentCount))
            {
                return(false);
            }

            return(true);
        }
예제 #22
0
 public MyRedBlackTreeNode(T data, RedBlackTreeNodeColor color,
                           MyRedBlackTreeNode <T> parent) : this(data)
 {
     Color  = color;
     Parent = parent;
 }
예제 #23
0
 public MyRedBlackTreeNode(bool isNull, MyRedBlackTreeNode <T> parent)
 {
     IsNull = isNull;
     Parent = parent;
     Color  = RedBlackTreeNodeColor.Black;
 }
예제 #24
0
        private void InsertHelper(MyRedBlackTreeNode <T> root, T data)
        {
            MyRedBlackTreeNode <T> node = null;

            if (root.IsNull)
            {
                node = new MyRedBlackTreeNode <T>(data, RedBlackTreeNodeColor.Red, root.Parent);
                if (root.Parent.Left == root)
                {
                    root.Parent.Left = node;
                }
                else
                {
                    root.Parent.Right = node;
                }
                root.Color = RedBlackTreeNodeColor.Red;
            }
            var compared = data.CompareTo(root.Data);

            if (compared <= 0 && root.Left != null)
            {
                InsertHelper(root.Left, data);
            }
            else if (root.Right != null)
            {
                InsertHelper(root.Right, data);
            }


            if (root.Parent == null || root.Parent.Color == RedBlackTreeNodeColor.Black)
            {
                if (node != null)
                {
                    root.Parent = null;
                }
                return;
            }

            var otherSibling = root.Parent.Parent.Left == root.Parent ?
                               root.Parent.Parent.Right : root.Parent.Parent.Left;

            if (otherSibling.Color == RedBlackTreeNodeColor.Red)
            {
                otherSibling.Color        = RedBlackTreeNodeColor.Black;
                otherSibling.Parent.Color = otherSibling.Parent == Root ? RedBlackTreeNodeColor.Black : RedBlackTreeNodeColor.Red;
                root.Parent.Color         = RedBlackTreeNodeColor.Black;
            }
            else if (root.Color == RedBlackTreeNodeColor.Red)
            {
                root = node ?? root;
                if (root.Parent.Right == root && root.Parent.Parent.Left == root.Parent)
                {
                    LeftRightRotation(root);
                    root = root.Left;
                }
                if (root.Parent.Left == root && root.Parent.Parent.Right == root.Parent)
                {
                    RightLeftRotation(root);
                    root = root.Right;
                }

                if (root.Parent.Left == root && root.Parent.Parent.Left == root.Parent)
                {
                    LeftLeftRotation(root);
                    root.Parent.Right.Color = RedBlackTreeNodeColor.Red;
                    root.Parent.Color       = RedBlackTreeNodeColor.Black;
                }

                if (root.Parent.Right == root && root.Parent.Parent.Right == root.Parent)
                {
                    RightRightRotation(root);
                    root.Parent.Color      = RedBlackTreeNodeColor.Black;
                    root.Parent.Left.Color = RedBlackTreeNodeColor.Red;
                }
            }
        }