Example #1
0
        /// <summary>
        /// java实现版本
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>

        public RedBlackNode <TKey, TValue> HeadNode1(TKey key)
        {
            RedBlackNode <TKey, TValue> p = rbTree;

            while (p != null)
            {
                int cmp = key.CompareTo(p.Key);
                if (cmp > 0)
                {
                    if (p.Right != null)
                    {
                        p = p.Right;
                    }
                    else
                    {
                        return(p);
                    }
                }
                else if (cmp < 0)
                {
                    if (p.Left != null)
                    {
                        p = p.Left;
                    }
                    else
                    {
                        RedBlackNode <TKey, TValue> parent = p.Parent;
                        RedBlackNode <TKey, TValue> ch     = p;
                        while (parent != null && ch == parent.Left)
                        {
                            ch     = parent;
                            parent = parent.Parent;
                        }
                        return(parent);
                    }
                }
                else
                {
                    return(p);
                }
            }
            return(null);
        }
Example #2
0
        ///<summary>
        /// RotateRight
        /// Rebalance the tree by rotating the nodes to the right
        ///</summary>
        public void RotateRight(RedBlackNode <TKey, TValue> x)
        {
            // pushing node x down and to the Right to balance the tree. x's Left child (y)
            // replaces x (since x < y), and y's Right child becomes x's Left child
            // (since it's < x but > y).

            RedBlackNode <TKey, TValue> y = x.Left;          // get x's Left node, this becomes y

            // set x's Right link
            x.Left = y.Right;                   // y's Right child becomes x's Left child

            // modify parents
            if (y.Right != sentinelNode)
            {
                y.Right.Parent = x;                             // sets y's Right Parent to x
            }
            if (y != sentinelNode)
            {
                y.Parent = x.Parent; // set y's Parent to x's Parent
            }
            if (x.Parent != null)    // null=rbTree, could also have used rbTree
            {                        // determine which side of it's Parent x was on
                if (x == x.Parent.Right)
                {
                    x.Parent.Right = y;         // set Right Parent to y
                }
                else
                {
                    x.Parent.Left = y;          // set Left Parent to y
                }
            }
            else
            {
                rbTree = y;                     // at rbTree, set it to y
            }
            // link x and y
            y.Right = x;                        // put x on y's Right
            if (x != sentinelNode)              // set y as x's Parent
            {
                x.Parent = y;
            }
        }
Example #3
0
        ///<summary>
        /// GetMaxKey
        /// Returns the maximum key value
        ///<summary>
        public TKey GetMaxKey()
        {
            RedBlackNode <TKey, TValue> treeNode = rbTree;

            if (treeNode == null || treeNode == sentinelNode)
            {
                throw (new RedBlackException("RedBlack tree is empty")
                {
                    Error = ReadBlackCode.Empty
                });
            }

            // traverse to the extreme right to find the largest key
            while (treeNode.Right != sentinelNode)
            {
                treeNode = treeNode.Right;
            }

            lastNodeFound = treeNode;

            return(treeNode.Key);
        }
Example #4
0
        /// <summary>
        /// 扩展一个方法
        /// 是否包含Key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Contains(TKey key)
        {
            int result = -1;
            RedBlackNode <TKey, TValue> treeNode = rbTree;     // begin at root

            // traverse tree until node is found
            while (treeNode != sentinelNode)
            {
                result = key.CompareTo(treeNode.Key);
                if (result == 0)
                {
                    return(true);
                }
                if (result < 0)
                {
                    treeNode = treeNode.Left;
                }
                else
                {
                    treeNode = treeNode.Right;
                }
            }
            return(false);
        }
Example #5
0
        ///<summary>
        /// Add
        /// args: ByVal key As IComparable, ByVal data As Object
        /// key is object that implements IComparable interface
        /// performance tip: change to use use int type (such as the hashcode)
        ///</summary>
        public void Add(TKey key, TValue data)
        {
            if (key == null || data == null)
            {
                throw (new RedBlackException("RedBlackNode<TKey,TValue> key and data must not be null")
                {
                    Error = ReadBlackCode.DataNull
                });
            }

            // traverse tree - find where node belongs
            int result = 0;
            // create new node
            RedBlackNode <TKey, TValue> node = new RedBlackNode <TKey, TValue>();
            RedBlackNode <TKey, TValue> temp = rbTree;               // grab the rbTree node of the tree

            while (temp != sentinelNode)
            {   // find Parent
                node.Parent = temp;
                result      = key.CompareTo(temp.Key);
                if (result == 0)
                {
                    throw (new RedBlackException("A Node with the same key already exists")
                    {
                        Error = ReadBlackCode.KeyExists
                    });
                }
                if (result > 0)
                {
                    temp = temp.Right;
                }
                else
                {
                    temp = temp.Left;
                }

                //
            }

            // setup node
            node.Key   = key;
            node.Value = data;
            node.Left  = sentinelNode;
            node.Right = sentinelNode;

            // insert node into tree starting at parent's location
            if (node.Parent != null)
            {
                result = node.Key.CompareTo(node.Parent.Key);
                if (result > 0)
                {
                    node.Parent.Right = node;
                }
                else
                {
                    node.Parent.Left = node;
                }
            }
            else
            {
                rbTree  = node;                 // first node added
                maxKey  = minKey = key;
                minNode = new RedBlackNode <TKey, TValue>()
                {
                    Key = minKey, Value = data
                };
                maxNode = new RedBlackNode <TKey, TValue>()
                {
                    Key = maxKey, Value = data
                };
            }

            RestoreAfterInsert(node);           // restore red-black properities

            lastNodeFound = node;

            intCount = intCount + 1;
            if (minKey.CompareTo(key) > 0)
            {
                minKey        = key;
                minNode.Key   = key;
                minNode.Value = data;
            }
            if (maxKey.CompareTo(key) < 0)
            {
                maxKey        = key;
                maxNode.Key   = key;
                maxNode.Value = data;
            }
        }
Example #6
0
 ///<summary>
 /// Clear
 /// Empties or clears the tree
 ///<summary>
 public void Clear()
 {
     rbTree   = sentinelNode;
     intCount = 0;
 }
Example #7
0
        ///<summary>
        /// RestoreAfterDelete
        /// Deletions from red-black trees may destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterDelete(RedBlackNode <TKey, TValue> x)
        {
            // maintain Red-Black tree balance after deleting node

            RedBlackNode <TKey, TValue> y;

            while (x != rbTree && x.Color == RedBlackNode <TKey, TValue> .BLACK)
            {
                if (x == x.Parent.Left) // determine sub tree from parent
                {
                    y = x.Parent.Right; // y is x's sibling
                    if (y.Color == RedBlackNode <TKey, TValue> .RED)
                    {                   // x is black, y is red - make both black and rotate
                        y.Color        = RedBlackNode <TKey, TValue> .BLACK;
                        x.Parent.Color = RedBlackNode <TKey, TValue> .RED;
                        RotateLeft(x.Parent);
                        y = x.Parent.Right;
                    }
                    if (y.Left.Color == RedBlackNode <TKey, TValue> .BLACK &&
                        y.Right.Color == RedBlackNode <TKey, TValue> .BLACK)
                    {                                               // children are both black
                        y.Color = RedBlackNode <TKey, TValue> .RED; // change parent to red
                        x       = x.Parent;                         // move up the tree
                    }
                    else
                    {
                        if (y.Right.Color == RedBlackNode <TKey, TValue> .BLACK)
                        {
                            y.Left.Color = RedBlackNode <TKey, TValue> .BLACK;
                            y.Color      = RedBlackNode <TKey, TValue> .RED;
                            RotateRight(y);
                            y = x.Parent.Right;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK;
                        y.Right.Color  = RedBlackNode <TKey, TValue> .BLACK;
                        RotateLeft(x.Parent);
                        x = rbTree;
                    }
                }
                else
                {   // right subtree - same as code above with right and left swapped
                    y = x.Parent.Left;
                    if (y.Color == RedBlackNode <TKey, TValue> .RED)
                    {
                        y.Color        = RedBlackNode <TKey, TValue> .BLACK;
                        x.Parent.Color = RedBlackNode <TKey, TValue> .RED;
                        RotateRight(x.Parent);
                        y = x.Parent.Left;
                    }
                    if (y.Right.Color == RedBlackNode <TKey, TValue> .BLACK &&
                        y.Left.Color == RedBlackNode <TKey, TValue> .BLACK)
                    {
                        y.Color = RedBlackNode <TKey, TValue> .RED;
                        x       = x.Parent;
                    }
                    else
                    {
                        if (y.Left.Color == RedBlackNode <TKey, TValue> .BLACK)
                        {
                            y.Right.Color = RedBlackNode <TKey, TValue> .BLACK;
                            y.Color       = RedBlackNode <TKey, TValue> .RED;
                            RotateLeft(y);
                            y = x.Parent.Left;
                        }
                        y.Color        = x.Parent.Color;
                        x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK;
                        y.Left.Color   = RedBlackNode <TKey, TValue> .BLACK;
                        RotateRight(x.Parent);
                        x = rbTree;
                    }
                }
            }
            x.Color = RedBlackNode <TKey, TValue> .BLACK;
        }
Example #8
0
        ///<summary>
        /// Delete
        /// Delete a node from the tree and restore red black properties
        ///<summary>
        private void Delete(RedBlackNode <TKey, TValue> z)
        {
            // A node to be deleted will be:
            //		1. a leaf with no children
            //		2. have one child
            //		3. have two children
            // If the deleted node is red, the red black properties still hold.
            // If the deleted node is black, the tree needs rebalancing

            RedBlackNode <TKey, TValue> x = new RedBlackNode <TKey, TValue>(); // work node to contain the replacement node
            RedBlackNode <TKey, TValue> y;                                     // work node

            // find the replacement node (the successor to x) - the node one with
            // at *most* one child.
            if (z.Left == sentinelNode || z.Right == sentinelNode)
            {
                y = z;                      // node has sentinel as a child
            }
            else
            {
                // z has two children, find replacement node which will
                // be the leftmost node greater than z
                y = z.Right;                        // traverse right subtree
                while (y.Left != sentinelNode)      // to find next node in sequence
                {
                    y = y.Left;
                }
            }

            // at this point, y contains the replacement node. it's content will be copied
            // to the valules in the node to be deleted

            // x (y's only child) is the node that will be linked to y's old parent.
            if (y.Left != sentinelNode)
            {
                x = y.Left;
            }
            else
            {
                x = y.Right;
            }

            // replace x's parent with y's parent and
            // link x to proper subtree in parent
            // this removes y from the chain
            x.Parent = y.Parent;
            if (y.Parent != null)
            {
                if (y == y.Parent.Left)
                {
                    y.Parent.Left = x;
                }
                else
                {
                    y.Parent.Right = x;
                }
            }
            else
            {
                rbTree = x;         // make x the root node
            }
            // copy the values from y (the replacement node) to the node being deleted.
            // note: this effectively deletes the node.
            if (y != z)
            {
                z.Key   = y.Key;
                z.Value = y.Value;
            }

            if (y.Color == RedBlackNode <TKey, TValue> .BLACK)
            {
                RestoreAfterDelete(x);
            }

            lastNodeFound = sentinelNode;
            UpdateBorder(z.Key);//更新边界
        }
Example #9
0
        ///<summary>
        /// RestoreAfterInsert
        /// Additions to red-black trees usually destroy the red-black
        /// properties. Examine the tree and restore. Rotations are normally
        /// required to restore it
        ///</summary>
        private void RestoreAfterInsert(RedBlackNode <TKey, TValue> x)
        {
            // x and y are used as variable names for brevity, in a more formal
            // implementation, you should probably change the names

            RedBlackNode <TKey, TValue> y;

            // maintain red-black tree properties after adding x
            while (x != rbTree && x.Parent.Color == RedBlackNode <TKey, TValue> .RED)
            {
                // Parent node is .Colored red;
                if (x.Parent == x.Parent.Parent.Left) // determine traversal path
                {                                     // is it on the Left or Right subtree?
                    y = x.Parent.Parent.Right;        // get uncle
                    if (y != null && y.Color == RedBlackNode <TKey, TValue> .RED)
                    {                                 // uncle is red; change x's Parent and uncle to black
                        x.Parent.Color = RedBlackNode <TKey, TValue> .BLACK;
                        y.Color        = RedBlackNode <TKey, TValue> .BLACK;
                        // grandparent must be red. Why? Every red node that is not
                        // a leaf has only black children
                        x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED;
                        x = x.Parent.Parent;    // continue loop with grandparent
                    }
                    else
                    {
                        // uncle is black; determine if x is greater than Parent
                        if (x == x.Parent.Right)
                        {   // yes, x is greater than Parent; rotate Left
                            // make x a Left child
                            x = x.Parent;
                            RotateLeft(x);
                        }
                        // no, x is less than Parent
                        x.Parent.Color        = RedBlackNode <TKey, TValue> .BLACK; // make Parent black
                        x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED;   // make grandparent black
                        RotateRight(x.Parent.Parent);                               // rotate right
                    }
                }
                else
                {   // x's Parent is on the Right subtree
                    // this code is the same as above with "Left" and "Right" swapped
                    y = x.Parent.Parent.Left;
                    if (y != null && y.Color == RedBlackNode <TKey, TValue> .RED)
                    {
                        x.Parent.Color        = RedBlackNode <TKey, TValue> .BLACK;
                        y.Color               = RedBlackNode <TKey, TValue> .BLACK;
                        x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RotateRight(x);
                        }
                        x.Parent.Color        = RedBlackNode <TKey, TValue> .BLACK;
                        x.Parent.Parent.Color = RedBlackNode <TKey, TValue> .RED;
                        RotateLeft(x.Parent.Parent);
                    }
                }
            }
            rbTree.Color = RedBlackNode <TKey, TValue> .BLACK;        // rbTree should always be black
        }
Example #10
0
        /// <summary>
        /// 小于等于该Key(没有测试)
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public SortedDictionary <TKey, TValue> HeadMap(TKey key)
        {
            SortedDictionary <TKey, TValue> dic = new SortedDictionary <TKey, TValue>();

            if (rbTree == null)
            {
                return(null);
            }
            if (minKey.CompareTo(key) > 0)
            {
                return(null);
            }
            RedBlackNode <TKey, TValue> treeNode = rbTree;     // begin at root
                                                               // traverse tree until node is found
            int result = -1;

            while (treeNode != sentinelNode)
            {
                result = key.CompareTo(treeNode.Key);
                if (result > 0)
                {
                    break;
                }
                else
                {
                    treeNode = treeNode.Left;
                }
            }
            //左右支路各一个线程查找;只能查找
            var taskLeft = Task.Factory.StartNew(() =>
            {
                LinkedList <RedBlackNode <TKey, TValue> > lstKeys = new LinkedList <RedBlackNode <TKey, TValue> >();
                Func <TKey, bool> p = new Func <TKey, bool>((k) =>
                {
                    if (k.CompareTo(key) <= 0)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                });
                PreOrderNode(rbTree, lstKeys, p);
                return(lstKeys);
            });
            var taskRight = Task.Factory.StartNew(() =>
            {
                LinkedList <RedBlackNode <TKey, TValue> > lstKeys = new LinkedList <RedBlackNode <TKey, TValue> >();
                Func <TKey, bool> p = new Func <TKey, bool>((k) =>
                {
                    if (k.CompareTo(key) <= 0)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                });
                PreOrderNode(rbTree.Right, lstKeys, p);
                return(lstKeys);
            });

            //
            if (taskLeft.Result != null)
            {
                foreach (var item in taskLeft.Result)
                {
                    dic[item.Key] = item.Value;
                }
                taskLeft.Result.Clear();
            }
            if (taskRight.Result != null)
            {
                foreach (var item in taskRight.Result)
                {
                    dic[item.Key] = item.Value;
                }
                taskRight.Result.Clear();
            }
            return(dic);
        }
        ///<summary>
        /// NextElement
        ///</summary>
        public object NextElement()
        {
            if (stack.Count == 0)
            {
                throw(new RedBlackException("Element not found")
                {
                    Error = ReadBlackCode.ElementNotFound
                });
            }

            // the top of stack will always have the next item
            // get top of stack but don't remove it as the next nodes in sequence
            // may be pushed onto the top
            // the stack will be popped after all the nodes have been returned
            RedBlackNode <TKey, TValue> node = (RedBlackNode <TKey, TValue>)stack.Peek();               //next node in sequence

            if (ascending)
            {
                if (node.Right == RedBlack <TKey, TValue> .sentinelNode)
                {
                    // yes, top node is lowest node in subtree - pop node off stack
                    RedBlackNode <TKey, TValue> tn = (RedBlackNode <TKey, TValue>)stack.Pop();
                    // peek at right node's parent
                    // get rid of it if it has already been used
                    while (HasMoreElements() && ((RedBlackNode <TKey, TValue>)stack.Peek()).Right == tn)
                    {
                        tn = (RedBlackNode <TKey, TValue>)stack.Pop();
                    }
                }
                else
                {
                    // find the next items in the sequence
                    // traverse to left; find lowest and push onto stack
                    RedBlackNode <TKey, TValue> tn = node.Right;
                    while (tn != RedBlack <TKey, TValue> .sentinelNode)
                    {
                        stack.Push(tn);
                        tn = tn.Left;
                    }
                }
            }
            else            // descending, same comments as above apply
            {
                if (node.Left == RedBlack <TKey, TValue> .sentinelNode)
                {
                    // walk the tree
                    RedBlackNode <TKey, TValue> tn = (RedBlackNode <TKey, TValue>)stack.Pop();
                    while (HasMoreElements() && ((RedBlackNode <TKey, TValue>)stack.Peek()).Left == tn)
                    {
                        tn = (RedBlackNode <TKey, TValue>)stack.Pop();
                    }
                }
                else
                {
                    // determine next node in sequence
                    // traverse to left subtree and find greatest node - push onto stack
                    RedBlackNode <TKey, TValue> tn = node.Left;
                    while (tn != RedBlack <TKey, TValue> .sentinelNode)
                    {
                        stack.Push(tn);
                        tn = tn.Right;
                    }
                }
            }

            // the following is for .NET compatibility (see MoveNext())
            Key   = node.Key;
            Value = node.Value;
            // ******** testing only ********
            try
            {
                parentKey = node.Parent.Key;        // testing only
            }
            catch (Exception e)
            {
                object o = e;                       // stop compiler from complaining
                parentKey = default(TKey);
            }
            if (node.Color == 0)                                // testing only
            {
                Color = "Red";
            }
            else
            {
                Color = "Black";
            }
            // ******** testing only ********
            if (keys)
            {
                return(node.Key);
            }
            else
            {
                return(node.Value);
            }
            //return keys == true ? node.Key : node.Data;
        }