예제 #1
0
        /*
         * RBInsert and RBDelete modify the tree which may result in a violation of the
         * red-black poperties. In order to fix this we may need to "move around" some of
         * the nodes as well as their colors.  LeftRotate and RightRotate help us do this.
         * */
        private Node LeftRotate(Node x)
        {
            Node y = x.right;

            x.right = y.left;
            if (y.left != NIL.Instance())
            {
                y.left.parent = x;
            }
            y.parent = x.parent;
            if (x.parent == NIL.Instance())
            {
                root = y;
            }
            else if (x == x.parent.left)
            {
                x.parent.left = y;
            }
            else
            {
                x.parent.right = y;
            }
            y.left   = x;
            x.parent = y;
            return(x);
        }
예제 #2
0
        private void LeftRotate(Node nodeToRotate)
        { // setting node which will come in place of nodeToRotate
            Node nodeToReplace = nodeToRotate.Right;

            //turn nodeToReplace's left subtree into nodeToRotate's right subtree
            nodeToRotate.Right = nodeToReplace.Left;
            if (nodeToReplace.Left != NIL.Instance())
            { // if left subtree exists make it's parent nodeToRotate
                nodeToReplace.Left.Parent = nodeToRotate;
            }
            if (nodeToReplace != NIL.Instance())
            { // link nodeToRotate parent to nodeToReplace
                nodeToReplace.Parent = nodeToRotate.Parent;
            }
            if (nodeToRotate.Parent == NIL.Instance())
            { // if nodeToRotate is the root, make nodeToReplace as new root
                Root = nodeToReplace;
            }
            if (nodeToRotate == nodeToRotate.Parent.Left)
            { // if nodeToRotate is a left child, nodeToReplace has to become left child of nodeToRotate's parent
                nodeToRotate.Parent.Left = nodeToReplace;
            }
            else
            { // if nodeToRotate is a right child, nodeToReplace has to become right child of nodeToRotate's parent
                nodeToRotate.Parent.Right = nodeToReplace;
            }
            // put nodeToRotate on nodeToReplace's left
            nodeToReplace.Left = nodeToRotate;
            // if nodeToRotate is not nil, make it's parent nodeToReplace
            if (nodeToRotate != NIL.Instance())
            {
                nodeToRotate.Parent = nodeToReplace;
            }
        }
예제 #3
0
 /*
  * To find the maximum of the three from node n (including
  * the root) we just keep going down the right braches until there
  * are no more nodes.
  * */
 private Node RBTreeMaximum(Node x)
 {
     while (x.right != NIL.Instance())
     {
         x = x.right;
     }
     return(x);
 }
예제 #4
0
 /*
  * To find the minimum of the tree from node n (including
  * the root) we just keep going down the left branches until there
  * are no more nodes.
  * */
 private Node RBTreeMinimum(Node x)
 {
     while (x.left != NIL.Instance())
     {
         x = x.left;
     }
     return(x);
 }
예제 #5
0
        /// <summary>
        /// passing through the tree by InOrderTraversal
        /// </summary>
        /// <param name="root"> root of a subtree to be passed </param>


        private void InOrderDisplay(Node root)
        {
            if (root != NIL.Instance())
            {
                InOrderDisplay(root.Left);
                Console.Write("Key is {0} and Value is {1} ", root.Key, root.Value);
                InOrderDisplay(root.Right);
            }
        }
예제 #6
0
        /// <summary>
        /// to restore the red-black properties
        /// </summary>
        /// <param name="NewAddedNode"> node which was inserted </param>
        private void RBT_InsertFixUp(Node NewAddedNode)
        {
            while (NewAddedNode != Root && NewAddedNode.Parent.color == COLOR.Red)
            {     // if parent of new added node is a left child
                if (NewAddedNode.Parent == NewAddedNode.Parent.Parent.Left)
                { // uncle of newAddedNode
                    Node uncle = NewAddedNode.Parent.Parent.Right;
                    if (uncle != NIL.Instance() && uncle.color == COLOR.Red)
                    {
                        NewAddedNode.Parent.color = COLOR.Black;
                        uncle.color = COLOR.Black;
                        NewAddedNode.Parent.Parent.color = COLOR.Red;
                        // make newNode's grandparent as the new newNode and repeat the steps
                        NewAddedNode = NewAddedNode.Parent.Parent;
                    } // if uncle is black and parent of newNode is not black there are 2 cases
                    // 1 case (left right case)
                    else if (NewAddedNode == NewAddedNode.Parent.Right)
                    {
                        NewAddedNode = NewAddedNode.Parent;
                        LeftRotate(NewAddedNode);
                    }

                    else
                    {// case 2 (left left case)
                        NewAddedNode.Parent.color        = COLOR.Black;
                        NewAddedNode.Parent.Parent.color = COLOR.Red;
                        RightRotate(NewAddedNode.Parent.Parent);
                    }
                }

                else
                {                                             // if parent of a new added node is right child
                    Node y = NewAddedNode.Parent.Parent.Left; // uncle of newNode
                    if (y != NIL.Instance() && y.color == COLOR.Red)
                    {
                        NewAddedNode.Parent.color = COLOR.Black;
                        y.color = COLOR.Black;
                        NewAddedNode.Parent.Parent.color = COLOR.Red;
                        NewAddedNode = NewAddedNode.Parent.Parent;
                    } // case 1 (right left)
                    else if (NewAddedNode == NewAddedNode.Parent.Left)
                    {
                        NewAddedNode = NewAddedNode.Parent;
                        RightRotate(NewAddedNode);
                    }

                    else
                    { //case 2(right right)
                        NewAddedNode.Parent.color        = COLOR.Black;
                        NewAddedNode.Parent.Parent.color = COLOR.Red;
                        LeftRotate(NewAddedNode.Parent.Parent);
                    }
                }
                Root.color = COLOR.Black;
            }
        }
예제 #7
0
        /*
         *
         * */
        public void RBInsert(Key kz, Value vz)
        {
            //Only add a new node if the key does not already exist
            Node newNode = new Node();

            newNode.key   = kz;
            newNode.val   = vz;
            newNode.left  = NIL.Instance();
            newNode.right = NIL.Instance();
            RBInsert(newNode);
        }
예제 #8
0
 /// <summary>
 /// displaying tree
 /// </summary>
 public void Display()
 {
     if (Root != NIL.Instance())
     {
         InOrderDisplay(Root);
     }
     else
     {
         throw new Exception("No tree");
     }
 }
예제 #9
0
        /// <summary>
        /// to delete node from the tree
        /// </summary>
        /// <param name="nodeToDelete"> node to be deleted </param>
        private void RBT_Delete(Node nodeToDelete)
        {
            Node node = nodeToDelete;

            /*
             * We have to store nodeToDelete's original color, because when we move a node
             * into it's postion and the color of nodeToDelete is black we must call DeleteFixup
             */
            COLOR originalColor = node.color;
            Node  x;

            // when nodeToDelete has one child we just need to replace nodeToDelete with the child

            if (nodeToDelete.Left == NIL.Instance())
            {
                x = nodeToDelete.Right;
                RBTransplant(nodeToDelete, nodeToDelete.Right);
            }
            else if (nodeToDelete.Right == NIL.Instance())
            {
                x = nodeToDelete.Left;
                RBTransplant(nodeToDelete, nodeToDelete.Left);
            }
            else
            {
                /*  if nodeToDelete has two children we have to find the successor (the smallest key
                 * that is larger than nodeToDelete) and move it into nodeToDelete's position */
                node          = RBTreeMinimum(nodeToDelete.Right);
                originalColor = node.color;
                x             = node.Right;
                //  if successor is right child
                if (node.Parent == nodeToDelete)
                {
                    x.Parent = node;
                }
                else
                { // succesor will move into nodeToDelete's position
                    RBTransplant(node, node.Right);
                    node.Right        = nodeToDelete.Right;
                    node.Right.Parent = node;
                }
                RBTransplant(nodeToDelete, node);
                node.Left        = nodeToDelete.Left;
                node.Left.Parent = node;
                node.color       = nodeToDelete.color;
            }
            // if node which was deleted is black, we restore red-black tree properties
            if (originalColor == COLOR.Black)
            {
                RBT_DeleteFixup(x);
            }
        }
예제 #10
0
 /*
  * Used to "replace" u with v.  Used when deleting a node and we need to replace
  * the deleted node with an other node from the tree.
  * */
 private void RBTransplant(Node u, Node v)
 {
     if (u.parent == NIL.Instance())
     {
         root = v;
     }
     else if (u == u.parent.left)
     {
         u.parent.left = v;
     }
     else
     {
         u.parent.right = v;
     }
     v.parent = u.parent;
 }
예제 #11
0
        /*
         * This is similar to insert for a binary search tree with a few differences.  We use NIL.Instance()
         * instead of null.
         * After inserting we call RBInsertFixup incase we've violated one of the red-black properties.
         * */
        private void RBInsert(Node z)
        {
            Node y = NIL.Instance();
            Node x = root;
            int  cmp;

            while (x != NIL.Instance())
            {
                y   = x;
                cmp = z.key.CompareTo(x.key);
                if (cmp < 0)
                {
                    x = x.left;
                }
                else if (cmp > 0)
                {
                    x = x.right;
                }
                else if (cmp == 0) //This key already exists, exit without adding it
                {
                    return;
                }
            }
            z.parent = y;
            cmp      = z.key.CompareTo(y.key);
            if (y == NIL.Instance())
            {
                root = z;
            }
            else if (cmp < 0)
            {
                y.left = z;
            }
            else if (cmp > 0)
            {
                y.right = z;
            }
            else if (cmp == 0)//This key already exists, exit without adding it
            {
                return;
            }
            z.left  = NIL.Instance();
            z.right = NIL.Instance();
            z.color = RBColor.RED;
            z       = RBInsertFixup(z);
        }
예제 #12
0
        /// <summary>
        ///  replaces the subtree rooted at node u with the subtree rooted at v
        /// </summary>
        /// <param name="u"> node to be replaced </param>
        /// <param name="v"> node which subtree will come into the place of u node's subtree </param>

        private void RBTransplant(Node x, Node y)
        { // if u is a root make v as a root
            if (x.Parent == NIL.Instance())
            {
                Root = y;
            }
            else if (x == x.Parent.Left)
            {
                x.Parent.Left = y;
            }
            else
            {
                x.Parent.Right = y;
            }
            // even if u.Parent is NIL we can assign it
            y.Parent = x.Parent;
        }
예제 #13
0
        /// <summary>
        /// Insert a given node
        /// </summary>
        /// <param name="newNode"> node to be inserted into the tree </param>
        private void Insert(Node newNode)
        { // if tree is empty, make NewNode as the root
            if (Root == NIL.Instance())
            {
                Root       = newNode;
                Root.color = COLOR.Black;
                return;
            }
            Node parentOfNewNode = NIL.Instance();
            Node a = Root;

            while (a != NIL.Instance())
            { // finding the right subtree to insert the newNode
                parentOfNewNode = a;
                if (newNode.Key.CompareTo(a.Key) < 0)
                {
                    a = a.Left;
                }
                else
                {
                    a = a.Right;
                }
            }
            newNode.Parent = parentOfNewNode;
            if (parentOfNewNode == NIL.Instance())
            {
                Root = newNode;
            }
            // finding in which subtree of b newNode have to be inserted
            else if (newNode.Key.CompareTo(parentOfNewNode.Key) >= 0)
            {
                parentOfNewNode.Right = newNode;
            }
            else
            {
                parentOfNewNode.Left = newNode;
            }
            // making inserted node's left and right children NIL and it's color RED
            newNode.Left  = NIL.Instance();
            newNode.Right = NIL.Instance();
            newNode.color = COLOR.Red;
            // because coloring red may cause a violation of one of the red-black properties we must guarantee that the red-black properties are preserved
            RBT_InsertFixUp(newNode);
        }
예제 #14
0
 // Adds an element with given key and value
 public void Add(TKey key, TValue value)
 {
     if (ContainsKey(key) == false)
     {
         Node NewNode = new Node
         {
             Key    = key,
             Value  = value,
             Left   = NIL.Instance(),
             Right  = NIL.Instance(),
             Parent = NIL.Instance()
         };
         Keys_List.Add(key);
         Key_Values.Add(value);
         Insert(NewNode);
         listForNodes.Add(new KeyValuePair <TKey, TValue>(key, value));
     }
     else
     {
         throw new Exception("Key is already inserted");
     }
 }
예제 #15
0
        /*
         * Delete node z and replace it with y.  If z has only one child we just replace z with
         * that child.  If z has two children then y should be z's successor.
         * */
        private void RBDelete(Node z)
        {
            Node x;
            //First, set y equal to z
            Node y = z;

            /*
             * We want to store z's original color so when we move a node
             * into z's postion and the value of yOriginalColor is black then we call
             * RBDeleteFixup.
             */
            RBColor yOriginalColor = y.color;

            /*
             * The first two if statements cover when z just has one child.  If
             * so, just replace z with the child
             */
            if (z.left == NIL.Instance())
            {
                x = z.right;
                RBTransplant(z, z.right);
            }
            else if (z.right == NIL.Instance())
            {
                x = z.left;
                RBTransplant(z, z.left);
            }
            else
            {
                /*
                 * z has two children.  First find the successor (the smallest key
                 * that is larger than z.  Move it into z's position by setting it's
                 * parent to z and re-assign child nodes.
                 */
                y = RBTreeMinimum(z.right);
                yOriginalColor = y.color;
                x = y.right;
                if (y.parent == z)
                {
                    x.parent = y;
                }
                else
                {
                    RBTransplant(y, y.right);
                    y.right        = z.right;
                    y.right.parent = y;
                }
                RBTransplant(z, y);
                y.left        = z.left;
                y.left.parent = y;
                y.color       = z.color;
            }

            /*
             * If node y was black, several problems may arise which RBDeleteFixup will fix.
             * */
            if (yOriginalColor == RBColor.BLACK)
            {
                RBDeleteFixup(x);
            }
        }
예제 #16
0
 /// <summary>
 /// Removes all items from the tree
 /// </summary>
 public void Clear()
 {
     Root = NIL.Instance();
 }