Exemple #1
0
 public bool IsRed(RBNode <T> node)
 {
     if (node == null)
     {
         return(false);
     }
     return(node.isRed);
 }
Exemple #2
0
        public void Insert(T value)
        {
            RBNode <T> node = new RBNode <T>(value);

            head       = InsertHelper(node, head);
            head.isRed = false;
            Count++;
        }
Exemple #3
0
        private RBNode <T> RightRotation(RBNode <T> node)
        {
            RBNode <T> temp = node.left;

            node.left        = temp.right;
            temp.right       = node;
            temp.isRed       = node.isRed;
            temp.right.isRed = true;
            return(temp);
        }
Exemple #4
0
        private RBNode <T> MoveRedRight(RBNode <T> node)
        {
            FlipColor(node);
            if (IsRed(node.left.left))
            {
                node = RightRotation(node);
                FlipColor(node);
            }

            return(node);
        }
 /// <summary>
 /// Finds the greatest child of the node given.
 /// </summary>
 /// <returns>The greatest child.</returns>
 /// <param name="me">The node that is to be searched. WHEN USING IN DELETE, MAKE SURE TO CALL THIS ON node.left NOT node.</param>
 RBNode <T> FindRightestChild(RBNode <T> me)
 {
     if (me.right is RBNullNode <T> )
     {
         return(me);
     }
     else
     {
         return(FindRightestChild(me.right));
     }
 }
 public void AddWithNode(RBValNode <T> newItem)
 {
     if (topNode == null)
     {
         topNode      = newItem;
         newItem.left = new RBNullNode <T>();
         InsertCheck(newItem);
         return;
     }
     AddLoop(newItem, topNode);
 }
Exemple #7
0
 public void PostOrder(RBNode <T> node)
 {
     if (node.left != null)
     {
         PostOrder(node.left);
     }
     if (node.right != null)
     {
         PostOrder(node.right);
     }
     Console.WriteLine(node.item);
 }
Exemple #8
0
 private void PreOrder(RBNode <T> node)
 {
     Console.WriteLine(node.item);
     if (node.left != null)
     {
         PreOrder(node.left);
     }
     if (node.right != null)
     {
         PreOrder(node.right);
     }
 }
Exemple #9
0
 /// <summary>
 /// Removes a value from the tree
 /// </summary>
 /// <param name="value">value to be removed</param>
 /// <param name="search"></param>
 /// <returns>the new root of the operation</returns>
 private RBNode <T> RemoveHelper(T value, RBNode <T> search)
 {
     if (search == null)
     {
         return(null);
     }
     if (value.CompareTo(search.item) < 0 && search.left != null) //moving left
     {
         if (!IsRed(search.left) && !IsRed(search.left.left))     //check if left node is 2 node
         {
             search = MoveRedLeft(search);
         }
         search.left = RemoveHelper(value, search.left);
     }
     else //moving right
     {
         if (IsRed(search.left))
         {
             search = RightRotation(search);
         }
         //found leaf value
         else if (value.CompareTo(search.item) == 0 && search.right == null)
         {
             return(null);
         }
         //if the value is found as an internal node
         else if (value.CompareTo(search.item) == 0 && (search.left != null || search.right != null))
         //copy the candidate value into the current node
         //recursivly delete the candidate value that was lower in the tree
         {
             if (!IsRed(search.right) && !IsRed(search.right.left))
             {
                 search = MoveRedRight(search);
             }
             RBNode <T> candidate = search.right;
             while (candidate.left != null)
             {
                 candidate = candidate.left; //bug here i think
             }
             search.item  = candidate.item;
             search.right = RemoveHelper(candidate.item, search.right);
         }
         //if our right node is a 2 node, MoveRedRight
         else if (!IsRed(search.right) && search.right != null && !IsRed(search.right.left))
         {
             search = MoveRedRight(search);
         }
         //continue right
         search.right = RemoveHelper(value, search.right);
     }
     //fixup
     return(FixUp(search));
 }
Exemple #10
0
        private RBNode <T> LeanLeft(RBNode <T> node)
        {
            if (IsRed(node.right))
            {
                node = LeftRotation(node);
            }
            if (IsRed(node.left) && IsRed(node.left.left))
            {
                node = RightRotation(node);
            }

            return(node);
        }
Exemple #11
0
        private RBNode <T> FixUp(RBNode <T> node)
        {
            node = LeanLeft(node);
            if (IsRed(node.left) && IsRed(node.right))
            {
                FlipColor(node);
            }
            if (node.left != null && !IsRed(node.left.left) && IsRed(node.left.right))
            {
                node = LeanLeft(node.left);
            }

            return(node);
        }
Exemple #12
0
 public RBValNode(T val, RBNode <T> leftNode = null, RBNode <T> rightNode = null, RBNode <T> parent = null)
 {
     base.val = val;
     left     = leftNode;
     if (leftNode == null)
     {
         left = new RBNullNode <T>();
     }
     right = rightNode;
     if (rightNode == null)
     {
         right = new RBNullNode <T>();
     }
     this.parent = parent;
 }
Exemple #13
0
        private RBNode <T> MoveRedLeft(RBNode <T> node)
        {
            FlipColor(node);
            if (IsRed(node.right.left))
            {
                node.right = RightRotation(node.right);
                node       = LeftRotation(node);
            }
            FlipColor(node);
            if (IsRed(node.right.right))
            {
                node.right = LeftRotation(node.right);
            }

            return(node);
        }
 /// <summary>
 /// Checks after deletion.
 /// </summary>
 /// <param name="u">The old node that got deleted</param>
 /// <param name="v">Te new node that replaced the old node. This can be a nil node</param>
 void DeleteCheck(RBNode <T> u, RBNode <T> v)
 { //v is node to be deleted, u is the one that replaces it
     if (u.color == Enums.Colors.red || v.color == Enums.Colors.red)
     {
         u.color = Enums.Colors.black;
     }
     else
     {
         //if both u and v are black
         if (u == topNode)
         {
             u.color = Enums.Colors.black;
         }
         else
         {
             FixDoubleBlack(u);
         }
     }
 }
        RBNode <T> FindNodeWithValueHelper(T val, RBNode <T> me)
        {
            if (me is RBNullNode <T> )
            {
                throw new Exception("Could not find node.");
            }
            int comparison = me.val.CompareTo(val);


            if (comparison > 0)
            {
                return(FindNodeWithValueHelper(val, me.left));
            }
            else if (comparison < 0)
            {
                return(FindNodeWithValueHelper(val, me.right));
            }
            else
            {
                return(me);
            }
        }
        void InsertCheck(RBNode <T> me)
        {
            if (me != topNode && me.parent.color != Enums.Colors.black) //If x is root, change color to BLACK
            {
                //Do the following if x's parent is not Black AND x is not root

                RBNode <T> uncle = (me.parent.parent.left == me.parent) ? me.parent.parent.right : me.parent.parent.left;

                if (uncle.color == Enums.Colors.red)
                {                                                //if x's uncle is red
                    me.parent.color        = Enums.Colors.black; //change color of parent to black
                    uncle.color            = Enums.Colors.black; //change color of uncle to black
                    me.parent.parent.color = Enums.Colors.red;   //make grandparent red
                    InsertCheck(me.parent.parent);               //rule check my grandparent
                }
                else
                {     //if x's uncle is black (OR NULLNODE: Nullnodes are black!)
                    if (me.parent.right == me)
                    { //if i'm a right child
                        if (me.parent.parent.right == me.parent)
                        {
                            //right-right case
                            RotateNodeLeft(me.parent.parent); //rotate grandparent left
                                                              //and swap grandparent and parent colors
                            var swapColor = me.parent.left.color;
                            me.parent.left.color = me.parent.color;
                            me.parent.color      = swapColor;
                        }
                        else if (me.parent.parent.left == me.parent)
                        {
                            //left-right case
                            RotateNodeLeft(me.parent);

                            RotateNodeRight(me.parent); //rotate grandparent right
                                                        //and swap grandparent and parent colors
                            var swapColor = me.right.color;
                            me.right.color = me.color;
                            me.color       = swapColor;
                        }
                        else
                        {
                            throw new Exception("AAH! My grandparent disowned my parent!");
                        }
                    }
                    else if (me.parent.left == me)
                    { //if i'm a left child
                        if (me.parent.parent.right == me.parent)
                        {
                            //right-left case
                            RotateNodeRight(me.parent);
                            RotateNodeLeft(me.parent); //rotate grandparent left
                                                       //and swap grandparent and parent colors (REWORDED: MY PARENT AND SIBILING)
                            var swapColor = me.left.color;
                            me.left.color = me.color;
                            me.color      = swapColor;
                        }
                        else if (me.parent.parent.left == me.parent)
                        {
                            //left-left case
                            RotateNodeRight(me.parent.parent); //rotate grandparent right
                            //and swap grandparent and parent colors
                            var swapColor = me.parent.right.color;
                            me.parent.right.color = me.parent.color;
                            me.parent.color       = swapColor;
                        }
                        else
                        {
                            throw new Exception("AAH! My grandparent disowned my parent!");
                        }
                    }
                    else
                    {
                        throw new Exception("AAH! The parents disowned the added node!");
                    }
                }
            }
            topNode.color = Enums.Colors.black;
        }
        void FixDoubleBlack(RBNode <T> doubleBlackNode)
        {
            RBNode <T> sibling;
            bool       isSiblingLeft;

            if (doubleBlackNode.parent.left == doubleBlackNode)
            {
                sibling       = doubleBlackNode.parent.right;
                isSiblingLeft = false;
            }
            else if (doubleBlackNode.parent.right == doubleBlackNode)
            {
                sibling       = doubleBlackNode.parent.left;
                isSiblingLeft = true;
            }
            else
            {
                throw new Exception("doubleBlackNode is not one of its parent's children!");
            }


            if (sibling.color == Enums.Colors.red)
            {
                //if sibling is red

                RBNode <T> oldParent = doubleBlackNode.parent;
                if (isSiblingLeft) //move sibling up
                {
                    RotateNodeRight(doubleBlackNode.parent);
                }
                else
                {
                    RotateNodeLeft(doubleBlackNode.parent);
                }

                if (oldParent.color == Enums.Colors.red)
                { //recolor old parent
                    oldParent.color = Enums.Colors.black;
                }
                else
                {
                    oldParent.color = Enums.Colors.red;
                }

                if (sibling.color == Enums.Colors.red)
                { //recolor old sibling.
                    sibling.color = Enums.Colors.black;
                }
                else
                {
                    sibling.color = Enums.Colors.red;
                }

                FixDoubleBlack(doubleBlackNode); //do it again, with the rotated tree
            }
            else if (sibling.left.color == Enums.Colors.red || sibling.right.color == Enums.Colors.red)
            {
                //if sibling has a red child

                if (sibling.left.color == Enums.Colors.red)
                {
                    //if sibling's red child is left child
                    if (sibling.parent.left == sibling)
                    {
                        //and sibling is a left child
                        //LEFT LEFT CASE

                        RotateNodeRight(sibling.parent);
                        var swap = sibling.parent.color;
                        sibling.parent.color = sibling.color;
                        sibling.color        = swap;
                    }
                    else
                    {
                        //and sibling is a right child
                        //RIGHT LEFT CASE

                        RotateNodeRight(sibling);

                        //and do right right case
                        RotateNodeLeft(sibling.parent);
                        var swap = sibling.parent.color;
                        sibling.parent.color = sibling.color;
                        sibling.color        = swap;
                    }
                }
                else
                {
                    //if sibling's red child is right child
                    if (sibling.parent.left == sibling)
                    {
                        //and sibling is a left child
                        //LEFT RIGHT CASE

                        RotateNodeLeft(sibling);

                        //and do left left case
                        RotateNodeRight(sibling.parent);
                        var swap = sibling.parent.color;
                        sibling.parent.color = sibling.color;
                        sibling.color        = swap;
                    }
                    else
                    {
                        //and sibling is a right child
                        //RIGHT RIGHT CASE

                        RotateNodeLeft(sibling.parent);
                        var swap = sibling.parent.color;
                        sibling.parent.color = sibling.color;
                        sibling.color        = swap;
                    }
                }
            }

            else
            {
                //if sibling is black and has no red children
                sibling.color = Enums.Colors.red;
                if (doubleBlackNode.parent.color == Enums.Colors.red)
                {
                    doubleBlackNode.parent.color = Enums.Colors.black;
                }
                else
                {
                    FixDoubleBlack(doubleBlackNode.parent);
                }
            }
        }
Exemple #18
0
 public void FlipColor(RBNode <T> node)
 {
     node.left.isRed  = !node.left.isRed;
     node.isRed       = !node.isRed;
     node.right.isRed = !node.right.isRed;
 }
Exemple #19
0
 public void Remove(T value)
 {
     head = RemoveHelper(value, head);
     Count--;
 }
 public RBTree(T firstNodeVal)
 {
     topNode = new RBValNode <T>(firstNodeVal);
 }
        public void Delete(RBNode <T> nodeToDelete)
        {
            //Do a BST delete. If Delete() is called on another node (in a special case) then the check is CANCELED on the original "deleted" node.
            if (nodeToDelete.left is RBNullNode <T> && nodeToDelete.right is RBNullNode <T> )
            {
                //no children
                RBNode <T> oldNode = nodeToDelete;
                RBNode <T> newNode = new RBNullNode <T>();



                DeleteCheck(oldNode, newNode);

                if (nodeToDelete == topNode) //roundabout way to say nodeToDelete = newNode. But that doesn't work because of refs
                {
                    topNode        = newNode;
                    topNode.parent = null;
                }
                else if (nodeToDelete.parent.left == nodeToDelete)
                {
                    nodeToDelete.parent.left = newNode;
                }
                else if (nodeToDelete.parent.right == nodeToDelete)
                {
                    nodeToDelete.parent.right = newNode;
                }
                else
                {
                    throw new Exception("Some kind of parenting issue");
                }
            }
            else if (nodeToDelete.right is RBNullNode <T> )
            {
                //the only child is left
                RBNode <T> oldNode = nodeToDelete;
                RBNode <T> newNode = nodeToDelete.left;


                DeleteCheck(oldNode, newNode);

                if (nodeToDelete == topNode)
                {                 //roundabout way to say nodeToDelete = newNode. But that doesn't work because of refs
                    topNode = newNode;
                }
                else if (nodeToDelete.parent.left == nodeToDelete)
                {
                    nodeToDelete.parent.left = newNode;
                }
                else if (nodeToDelete.parent.right == nodeToDelete)
                {
                    nodeToDelete.parent.right = newNode;
                }
                else
                {
                    throw new Exception("Some kind of parenting issue");
                }
            }
            else if (nodeToDelete.left is RBNullNode <T> )
            {
                //only child is right
                RBNode <T> oldNode = nodeToDelete;
                RBNode <T> newNode = nodeToDelete.right;

                DeleteCheck(oldNode, newNode);

                if (nodeToDelete == topNode)
                {                 //roundabout way to say nodeToDelete = newNode. But that doesn't work because of refs
                    topNode = newNode;
                }
                else if (nodeToDelete.parent.left == nodeToDelete)
                {
                    nodeToDelete.parent.left = newNode;
                }
                else if (nodeToDelete.parent.right == nodeToDelete)
                {
                    nodeToDelete.parent.right = newNode;
                }
                else
                {
                    throw new Exception("Some kind of parenting issue");
                }
            }
            else
            {
                RBNode <T> replacer = FindRightestChild(nodeToDelete.left);
                nodeToDelete.val = replacer.val;
                Delete(replacer);
            }
        }
 public RBTree()
 {
     topNode = null;
 }