示例#1
0
        /// <summary>
        ///   is        node.left.key  &lt;=  node.key  &lt;= node.right.key
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public bool IsTreeNode(RBTreeNode <K, V> node)
        {
            if (node == null)
            {
                return(true);
            }

            if (node.Left != null && node.Left.Key.CompareTo(node.Key) > 0)
            {
                return(false);
            }

            if (node.Right != null && node.Right.Key.CompareTo(node.Key) < 0)
            {
                return(false);
            }

            return(true);
        }
示例#2
0
        /// <summary>
        /// Red Black insert
        /// </summary>
        /// <param name="key"></param>
        /// <param name="val"></param>
        public void Insert(K key, V val)
        {
            RBTreeNode <K, V> node = null, inserted = new RBTreeNode <K, V>(key, val);

            count++;
            RBTreeNode <K, V> x = root;

            while (x != null)
            {
                node = x;
                node.Size++;
                if (key.CompareTo(x.Key) < 0)
                {
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            inserted.Parent = node;

            //first insert a node
            if (node == null)
            {
                root = inserted;
            }
            else if (inserted.Key.CompareTo(node.Key) < 0)
            {
                node.Left = inserted;
            }
            else
            {
                node.Right = inserted;
            }

            inserted.Left  = inserted.Right = null;
            inserted.Color = Color.RED;
            inserted.Size  = 1;
            //fix up the insert node, so red black tree reserve
            InsertFixup(inserted);
        }
示例#3
0
        /// <summary>
        /// When TRANSPLANT replaces the subtree rooted at node u with
        /// the subtree rooted at node v , node u’s parent becomes node v’s parent, and u’s parent ends up having v as its appropriate child.
        /// </summary>
        /// <param name="u"></param>
        /// <param name="v"></param>
        private void Transplant(RBTreeNode <K, V> u, RBTreeNode <K, V> v)
        {
            if (u.Parent == null)
            {
                root = v;
            }
            else if (u == u.Parent.Left)
            {
                u.Parent.Left = v;
            }
            else
            {
                u.Parent.Right = v;
            }

            if (v != null)
            {
                v.Parent = u.Parent;
            }
        }
示例#4
0
        /// <summary>
        /// select the ith smallest tree node in inorder tree walk sequence rooted at root.
        /// null if can't find one
        /// it runs at O(lgn)
        /// </summary>
        /// <param name="root"></param>
        /// <param name="i"></param>
        /// <returns></returns>
        private RBTreeNode <K, V> Select(RBTreeNode <K, V> root, int i)
        {
            if (root == null)
            {
                return(null);
            }
            int r = 1 + (root.Left == null ? 0 : root.Left.Size);

            if (i == r)
            {
                return(root);
            }
            else if (i < r)
            {
                return(Select(root.Left, i));
            }
            else
            {
                return(Select(root.Right, i - r));
            }
        }
示例#5
0
        /// <summary>
        /// find successor
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public Tuple <K, V> Successor(RBTreeNode <K, V> root)
        {
            if (root == null)
            {
                return(null);
            }

            if (root.Right != null)
            {
                return(Minimum(root.Right));
            }

            RBTreeNode <K, V> node = root.Parent;

            while (node != null && root == node.Right)
            {
                root = node;
                node = node.Parent;
            }
            return(node == null ? null : new Tuple <K, V>(node.Key, node.Value));
        }
示例#6
0
        /// <summary>
        /// find successor
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public RBTreeNode <K, V> Successor_(RBTreeNode <K, V> root)
        {
            if (root == null)
            {
                return(null);
            }

            if (root.Right != null)
            {
                return(Minimum_(root.Right));
            }

            RBTreeNode <K, V> node = root.Parent;

            while (node != null && root == node.Right)
            {
                root = node;
                node = node.Parent;
            }
            return(node);
        }
示例#7
0
        /// <summary>
        /// find predecessor
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public Tuple <K, V> Predecessor(RBTreeNode <K, V> root)
        {
            if (root == null)
            {
                return(null);
            }

            if (root.Left != null)
            {
                return(Maximum(root.Left));
            }

            RBTreeNode <K, V> node = root.Parent;

            while (node != null && root == node.Left)
            {
                root = node;
                node = node.Parent;
            }

            return(node == null ? null : new Tuple <K, V>(node.Key, node.Value));
        }
示例#8
0
        /// <summary>
        /// find predecessor
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public RBTreeNode <K, V> Predecessor_(RBTreeNode <K, V> root)
        {
            if (root == null)
            {
                return(null);
            }

            if (root.Left != null)
            {
                return(Maximum_(root.Left));
            }

            RBTreeNode <K, V> node = root.Parent;

            while (node != null && root == node.Left)
            {
                root = node;
                node = node.Parent;
            }

            return(node);
        }
示例#9
0
        private RBTreeNode <K, V> Search_(K key, RBTreeNode <K, V> root)
        {
            if (root == null)
            {
                return(null);
            }

            int i = root.Key.CompareTo(key);

            if (i == 0)
            {
                return(root);
            }
            else if (i > 0)
            {
                return(Search_(key, root.Left));
            }
            else
            {
                return(Search_(key, root.Right));
            }
        }
示例#10
0
        /// <summary>
        /// right rotate
        /// </summary>
        /// <param name="x">x must have left child</param>
        private void RightRotate(RBTreeNode <K, V> x)
        {
            if (x.Left == null)
            {
                return;
            }

            RBTreeNode <K, V> y = x.Left;

            x.Left = y.Right;

            if (y.Right != null)
            {
                y.Right.Parent = x;
            }

            y.Parent = x.Parent;

            if (x.Parent == null)
            {
                root = y;
            }
            else if (x == x.Parent.Left)
            {
                x.Parent.Left = y;
            }
            else
            {
                x.Parent.Right = y;
            }

            y.Right  = x;
            x.Parent = y;

            y.Size = x.Size;
            x.Size = Size(x.Left) + Size(x.Right) + 1;
        }
示例#11
0
 private bool IsRed(RBTreeNode <K, V> rBTreeNode)
 {
     return(!IsBlack(rBTreeNode));
 }
示例#12
0
 private bool IsBlack(RBTreeNode <K, V> rBTreeNode)
 {
     return(rBTreeNode == null || rBTreeNode.Color == Color.BLACK);
 }
示例#13
0
        /// <summary>
        /// x must have at most one child
        /// 1)if the root deleted, then a red (must be red or it have none children) child be new root
        /// 2)all x's path black height less 1
        /// 3)the father and x node may be both red
        /// </summary>
        /// <param name="x"></param>
        /// <param name="parent"></param>
        private void DeleteFixUp(RBTreeNode <K, V> x, RBTreeNode <K, V> parent)
        {
            RBTreeNode <K, V> w = null;

            while (x != root && IsBlack(x))
            {
                //if x is not root then the parent is not null
                // x is double black & x can be null
                if (x == parent.Left)
                {
                    //since node x is double black, node w can not be null, because the number of blacks on simple path from x.p to the leaf w would be smaller than the the number on simple path from x.p to x.
                    w = parent.Right;
                    if (IsRed(w))
                    {
                        w.Color      = Color.BLACK;
                        parent.Color = Color.RED;
                        LeftRotate(parent);
                        w = parent.Right;
                        //w still can not be null here
                    }

                    if (w != null && IsBlack(w.Left) && IsBlack(w.Right))
                    {
                        w.Color = Color.RED;
                        x       = parent;
                        parent  = parent.Parent;
                    }
                    else if (w != null)
                    {
                        if (IsBlack(w.Right))
                        {
                            //w.left is red
                            if (w.Left != null)
                            {
                                w.Left.Color = Color.BLACK;
                            }
                            w.Color = Color.RED;
                            RightRotate(w);
                            w = parent.Right;
                        }
                        if (w != null)
                        {
                            w.Color      = parent.Color;
                            parent.Color = Color.BLACK;
                            if (w.Right != null)
                            {
                                w.Right.Color = Color.BLACK;
                            }
                            LeftRotate(parent);
                            x = root;
                        }
                    }
                }
                else
                {
                    w = parent.Left;
                    if (IsRed(w))
                    {
                        w.Color      = Color.BLACK;
                        parent.Color = Color.RED;
                        RightRotate(parent);
                        w = parent.Left;
                    }
                    if (w != null && IsBlack(w.Left) && IsBlack(w.Right))
                    {
                        w.Color = Color.RED;
                        x       = parent;
                        parent  = parent.Parent;
                    }
                    else if (w != null)
                    {
                        if (IsBlack(w.Left))
                        {
                            if (w.Right != null)
                            {
                                w.Right.Color = Color.BLACK;
                            }
                            w.Color = Color.RED;
                            LeftRotate(w);
                            w = parent.Left;
                        }
                        if (w != null)
                        {
                            w.Color      = parent.Color;
                            parent.Color = Color.BLACK;
                            if (w.Left != null)
                            {
                                w.Left.Color = Color.BLACK;
                            }
                            RightRotate(parent);
                            //Setting x to be the root causes the while loop to terminate when it tests the loop condition.
                            x = root;
                        }
                    }
                }
            }
            //if x origin color is red,then color black, which add 1 black at the path
            if (x != null)
            {
                x.Color = Color.BLACK;
            }
        }
示例#14
0
        /// <summary>
        /// delete the node
        /// </summary>
        /// <param name="node"></param>
        public void Delete(RBTreeNode <K, V> node)
        {
            if (node == null)
            {
                return;
            }

            count--;

            //node x that moves into node y’s original position.
            //node y as the node either removed from the tree or moved within the tree.
            //parent is the path where size need to minus 1
            RBTreeNode <K, V> y = node, x = null, parent = null;
            Color             yOriginColor = y.Color;

            if (node.Left == null)
            {
                x      = node.Right;
                parent = node.Parent;
                Transplant(node, node.Right);
            }
            else if (node.Right == null)
            {
                x      = node.Left;
                parent = node.Parent;
                Transplant(node, node.Left);
            }
            else
            {
                y            = Minimum_(node.Right);
                yOriginColor = y.Color;
                x            = y.Right;
                if (y.Parent == node)
                {
                    parent = y;
                    y.Size = node.Size;
                }
                else
                {
                    //the post one is not right the right one
                    parent = y.Parent;
                    y.Size = node.Size;
                    Transplant(y, y.Right);
                    //because the post one is not the right child, then node.right is not null
                    y.Right        = node.Right;
                    y.Right.Parent = y;
                }

                Transplant(node, y);
                y.Left = node.Left;
                //node.left is not null
                y.Left.Parent = y;
                y.Color       = node.Color;
            }

            RBTreeNode <K, V> pNode = parent;

            while (pNode != null)
            {
                pNode.Size--;
                pNode = pNode.Parent;
            }


            if (yOriginColor == Color.BLACK)
            {
                // x can be null. if y originColor red, no violation of rbt
                // node x moves into node y’s original position
                //we can sure here parent is the parent of x ,but because x can be null, we need to use parent as a parameter
                DeleteFixUp(x, parent);
            }
            //if yOriginColor is red, then x is null and y is leaf node
        }
示例#15
0
 /// <summary>
 /// find the number of nodes in the tree
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 private int Size(RBTreeNode <K, V> node)
 {
     return(node == null ? 0 : node.Size);
 }