Пример #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
    private Node rightRotate(Node x)
    {
        Node y = x.left;

        x.left = y.right;
        if (y.right != NIL.NilNode())
        {
            y.right.parent = x;
        }
        y.parent = x.parent;
        if (x.parent == NIL.NilNode())
        {
            root = y;
        }
        else if (x == x.parent.right)
        {
            x.parent.right = y;
        }
        else
        {
            x.parent.left = y;
        }
        y.right  = x;
        x.parent = y;
        return(x);
    }
Пример #4
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);
 }
Пример #5
0
 private static int getHeight(Node n)
 {
     if (n == null || n == NIL.NilNode())
     {
         return(-1);
     }
     return(1 + Max(getHeight(n.left), getHeight(n.right)));
 }
Пример #6
0
 private Node getMin(Node x)
 {
     while (x.left != NIL.NilNode())
     {
         x = x.left;
     }
     return(x);
 }
Пример #7
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);
 }
Пример #8
0
 private Node getMax(Node x)
 {
     while (x.right != NIL.NilNode())
     {
         x = x.right;
     }
     return(x);
 }
Пример #9
0
 private int rightBlackHeight(Node n)
 {
     if (n == NIL.NilNode())
     {
         return(1);
     }
     return(n.color == Color.BLACK ? rightBlackHeight(n.left) + 1 : rightBlackHeight(n.left));
 }
Пример #10
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);
            }
        }
Пример #11
0
    public void delete(int key)
    {
        Node search = find(key);

        if (search != NIL.NilNode())
        {
            delete(search);
        }
    }
Пример #12
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;
            }
        }
Пример #13
0
    public void insert(int key)
    {
        digits = Max(digits, (key.ToString().Length % 2 == 1 ? key.ToString().Length + 1 : key.ToString().Length));
        Node newNode = new Node();

        newNode.key   = key;
        newNode.left  = NIL.NilNode();
        newNode.right = NIL.NilNode();
        insert(newNode);
    }
Пример #14
0
 /// <summary>
 /// displaying tree
 /// </summary>
 public void Display()
 {
     if (Root != NIL.Instance())
     {
         InOrderDisplay(Root);
     }
     else
     {
         throw new Exception("No tree");
     }
 }
Пример #15
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);
        }
Пример #16
0
 private bool checktree(Node n)
 {
     if (n == NIL.NilNode())
     {
         return(true);
     }
     if (!(checktree(n.left) && checktree(n.right)))
     {
         WriteLine(n.key + " HEIGHT NOT EVEN");
     }
     return((leftBlackHeight(n.left) == rightBlackHeight(n.right)) && checktree(n.left) && checktree(n.right));
 }
Пример #17
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);
            }
        }
Пример #18
0
 private Node find(Node x, int key)
 {
     if (x == null || x == NIL.NilNode() || key == x.key)
     {
         return(x);
     }
     if (key < x.key)
     {
         return(find(x.left, key));
     }
     else
     {
         return(find(x.right, key));
     }
 }
Пример #19
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;
 }
Пример #20
0
    private void delete(Node z)
    {
        Node y;
        Node x;

        if (z.left == NIL.NilNode() || z.right == NIL.NilNode())
        {
            y = z;
        }
        else
        {
            y = getMin(z.right);
        }

        if (y.left != NIL.NilNode())
        {
            x = y.left;
        }
        else
        {
            x = y.right;
        }
        x.parent = y.parent;
        if (y.parent == NIL.NilNode())
        {
            root = x;
        }
        else
        {
            if (y.parent.left == y)
            {
                y.parent.left = x;
            }
            else
            {
                y.parent.right = x;
            }
        }
        if (y != z)
        {
            z.key = y.key;
        }
        if (y.color == Color.BLACK)
        {
            deleteFixup(x);
        }
    }
Пример #21
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;
        }
Пример #22
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);
        }
Пример #23
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);
        }
Пример #24
0
    private void insert(Node z)
    {
        Node y = NIL.NilNode();
        Node x = root;

        while (x != NIL.NilNode())
        {
            y = x;
            if (z.key < x.key)
            {
                x = x.left;
            }
            else if (z.key > x.key)
            {
                x = x.right;
            }
            else if (z.key == x.key)
            {
                return;
            }
        }
        z.parent = y;
        if (y == NIL.NilNode())
        {
            root = z;
        }
        else if (z.key < y.key)
        {
            y.left = z;
        }
        else if (z.key > y.key)
        {
            y.right = z;
        }
        else if (z.key == y.key)
        {
            return;
        }
        z.left  = NIL.NilNode();
        z.right = NIL.NilNode();
        z.color = Color.RED;
        z       = insertFixup(z);
    }
Пример #25
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");
     }
 }
Пример #26
0
    //===================PRINT===========================
    public void print()
    {
        if (root == null || root == NIL.NilNode())
        {
            WriteLine("Tree is empty");
            return;
        }
        NodeList[] levels = getTreePerLevels();

        int height = getHeight(this.root);

        for (int i = height + 1; i >= 0; i--)
        {
            int padding = formula(i, this.digits);
            int num     = height + 1 - i;
            for (int j = 0; j < Math.Pow(2, num); j++)
            {
                if (levels[num][j] != null)
                {
                    if (levels[num][j] != NIL.NilNode())
                    {
                        encapsulate(padding, j, levels[num][j].key, this.digits, levels[num][j].color);
                    }
                    else
                    {
                        encapsulate(padding, j, int.MinValue, this.digits, Color.BLACK);
                    }
                }
                else
                {
                    encapsulate(padding, j, int.MinValue, this.digits, Color.Blue);
                }
            }
            WriteLine();
        }
    }
Пример #27
0
 static void populate(ref NodeList[] levels, Node n, int level)
 {
     if (n == null)
     {
         levels[level].add(null);
         int j = 1;
         for (int i = level + 1; i < levels.Length; i++)
         {
             for (int k = 1; k <= j; k++)
             {
                 levels[i].add(null);
                 levels[i].add(null);
             }
             j++;
         }
         return;
     }
     if (n == NIL.NilNode())
     {
         levels[level].add(NIL.NilNode());
         int j = 1;
         for (int i = level + 1; i < levels.Length; i++)
         {
             for (int k = 1; k <= j; k++)
             {
                 levels[i].add(null);
                 levels[i].add(null);
             }
             j++;
         }
         return;
     }
     populate(ref levels, n.left, level + 1);
     levels[level].add(n);
     populate(ref levels, n.right, level + 1);
 }
Пример #28
0
 /// <summary>
 /// Removes all items from the tree
 /// </summary>
 public void Clear()
 {
     Root = NIL.Instance();
 }
Пример #29
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);
            }
        }