예제 #1
0
        /// <summary>
        /// Right rotation of the tree around y.
        /// </summary>
        static private void RightRotate(RbTreeNode y)
        {
            RbTreeNode x = y.Left;

            y.Left = x.Right;

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

            x.Parent = y.Parent;

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

            x.Right  = y;
            y.Parent = x;
        }
예제 #2
0
        /// <summary>
        /// Left rotation of the tree around x.
        /// </summary>
        private void LeftRotate(RbTreeNode x)
        {
            RbTreeNode y = x.Right;

            x.Right = y.Left;

            if (y.Left != RbTreeNode.Nil)
            {
                y.Left.Parent = x;
            }

            y.Parent = x.Parent;

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

            y.Left   = x;
            x.Parent = y;
        }
예제 #3
0
        public RbTreeNode Next(RbTreeNode x)
        {
            RbTreeNode node  = this._root;
            RbTreeNode right = x.Right;

            if (right != RbTreeNode.Nil)
            {
                while (right.Left != RbTreeNode.Nil)
                {
                    right = right.Left;
                }
                return(right);
            }
            right = x.Parent;
            while (x == right.Right)
            {
                x     = right;
                right = right.Parent;
            }
            if (right == node)
            {
                return(RbTreeNode.Nil);
            }
            return(right);
        }
예제 #4
0
        public RbTreeNode Prev(RbTreeNode x)
        {
            RbTreeNode node = this._root;
            RbTreeNode left = x.Left;

            if (left != RbTreeNode.Nil)
            {
                while (left.Right != RbTreeNode.Nil)
                {
                    left = left.Right;
                }
                return(left);
            }
            left = x.Parent;
            while (x == left.Left)
            {
                if (left == node)
                {
                    return(RbTreeNode.Nil);
                }
                x    = left;
                left = left.Parent;
            }
            return(left);
        }
예제 #5
0
        /// <summary>
        /// Node in the tree that precedes given node.
        /// </summary>
        /// <remarks>
        /// If x is logically fisrt node, returns RbTreeNode.Nil.
        /// </remarks>
        public RbTreeNode Prev(RbTreeNode x)
        {
            RbTreeNode root = _root;
            RbTreeNode y    = x.Left;


            if (y != RbTreeNode.Nil)
            {
                while (y.Right != RbTreeNode.Nil)
                { /* returns the maximum of the left subtree of x */
                    y = y.Right;
                }
                return(y);
            }
            else
            {
                y = x.Parent;
                while (x == y.Left)
                {
                    if (y == root)
                    {
                        return(RbTreeNode.Nil);
                    }
                    x = y;
                    y = y.Parent;
                }
                return(y);
            }
        }
예제 #6
0
        /// <summary>
        /// Node in the tree that follows given node.
        /// </summary>
        /// <remarks>
        /// If x is logically last node in the tree, returns RbTreeNode.Nil.
        /// </remarks>
        public RbTreeNode Next(RbTreeNode x)
        {
            RbTreeNode root = _root;
            RbTreeNode y    = x.Right;

            if (y != RbTreeNode.Nil)
            {
                while (y.Left != RbTreeNode.Nil)
                { /* returns the minimum of the right subtree of x */
                    y = y.Left;
                }

                return(y);
            }
            else
            {
                y = x.Parent;

                while (x == y.Right)
                { /* sentinel used instead of checking for nil */
                    x = y;
                    y = y.Parent;
                }

                if (y == root)
                {
                    return(RbTreeNode.Nil);
                }
                return(y);
            }
        }
예제 #7
0
 /// <summary>
 /// Creates a node from field values.
 /// </summary>
 public RbTreeNode(object val, RbTreeNode parent, RbTreeNode left, RbTreeNode right, bool isRed)
 {
     Value = val;
     Parent = parent;
     Left = left;
     Right = right;
     IsRed = isRed;
 }
예제 #8
0
 /// <summary>
 /// Creates a node from field values.
 /// </summary>
 public RbTreeNode(object val, RbTreeNode parent, RbTreeNode left, RbTreeNode right, bool isRed)
 {
     Value  = val;
     Parent = parent;
     Left   = left;
     Right  = right;
     IsRed  = isRed;
 }
예제 #9
0
 public RbTreeNode(object val, RbTreeNode parent, RbTreeNode left, RbTreeNode right, bool isRed)
 {
     this.Value  = val;
     this.Parent = parent;
     this.Left   = left;
     this.Right  = right;
     this.IsRed  = isRed;
 }
예제 #10
0
        public void Erase(RbTreeNode z)
        {
            RbTreeNode node;
            RbTreeNode node3 = this._root;

            if ((z.Left == RbTreeNode.Nil) || (z.Right == RbTreeNode.Nil))
            {
                node = z;
            }
            else
            {
                node = this.Next(z);
            }
            RbTreeNode x = (node.Left == RbTreeNode.Nil) ? node.Right : node.Left;

            if (this._root == (x.Parent = node.Parent))
            {
                this._root.Left = x;
            }
            else if (node == node.Parent.Left)
            {
                node.Parent.Left = x;
            }
            else
            {
                node.Parent.Right = x;
            }
            if (!node.IsRed)
            {
                this.DeleteFixUp(x);
            }
            if (node != z)
            {
                node.Left     = z.Left;
                node.Right    = z.Right;
                node.Parent   = z.Parent;
                node.IsRed    = z.IsRed;
                z.Left.Parent = z.Right.Parent = node;
                if (z == z.Parent.Left)
                {
                    z.Parent.Left = node;
                }
                else
                {
                    z.Parent.Right = node;
                }
            }
            IDisposable disposable = z.Value as IDisposable;

            if (disposable != null)
            {
                disposable.Dispose();
            }
        }
예제 #11
0
 public bool MoveNext()
 {
     if (this._currentNode == null)
     {
         this._currentNode = this._tree.First;
     }
     else
     {
         this._currentNode = this._tree.Next(this._currentNode);
     }
     return(!this._currentNode.IsNull);
 }
예제 #12
0
        public bool MoveNext()
        {
            if (_currentNode == null)
            {
                _currentNode = _tree.First;
            }
            else
            {
                _currentNode = _tree.Next(_currentNode);
            }

            return !_currentNode.IsNull;
        }
예제 #13
0
        public bool MoveNext()
        {
            if (_currentNode == null)
            {
                _currentNode = _tree.First;
            }
            else
            {
                _currentNode = _tree.Next(_currentNode);
            }

            return(!_currentNode.IsNull);
        }
예제 #14
0
        public int Erase(object val)
        {
            RbTreeNode x     = this.LowerBound(val);
            RbTreeNode node2 = this.UpperBound(val);
            int        num   = 0;

            while (x != node2)
            {
                RbTreeNode z = x;
                x = this.Next(x);
                this.Erase(z);
                num++;
            }
            return(num);
        }
예제 #15
0
 public object Find(object key)
 {
     if (key != null)
     {
         RbTreeNode node = this._tree.LowerBound(key);
         if (node.IsNull)
         {
             return(null);
         }
         if (this.Comparer.Compare(node.Value, key) == 0)
         {
             return(node.Value);
         }
     }
     return(null);
 }
예제 #16
0
        /// <summary>
        /// Removes object(s) from the tree.
        /// </summary>
        /// <param name="val">Object to remove.</param>
        /// <returns>Number of nodes removed.</returns>
        /// <remarks>
        /// Finds and removes all nodes in the tree whose values compare equal to val.
        /// Returns number of removed nodes (possibly zero).
        /// </remarks>
        public int Erase(object val)
        {
            RbTreeNode first    = LowerBound(val);
            RbTreeNode last     = UpperBound(val);
            int        nDeleted = 0;

            while (first != last)
            {
                RbTreeNode temp = first;
                first = Next(first);
                Erase(temp);
                ++nDeleted;
            }

            return(nDeleted);
        }
예제 #17
0
        /// <summary>
        /// Inserts item based only on its value, probably violating Left/Right property.
        /// </summary>
        /// <param name="z">Node to insert.</param>
        ///
        /// <param name="allowDuplicates">If true, will insert the node even if equal node
        /// already exists in the tree. If false, behavior depends on replaceIfDuplicate.
        /// </param>
        ///
        /// <param name="replaceIfDuplicate">Matters only if node equal to z exists in the
        /// tree and allowDuplicates is false. If replaceIfDuplicate is true, z replaces
        /// existing node. Otherwise, tree does not change.
        /// </param>
        /// <returns>
        /// result.NewNode is true if new node was inserted to the tree'
        /// result.Node contains newly inserted node if any, or node equal to z
        /// </returns>
        ///
        private InsertResult BinaryInsert(RbTreeNode z, bool allowDuplicates, bool replaceIfDuplicate)
        {
            z.Left  = RbTreeNode.Nil;
            z.Right = RbTreeNode.Nil;

            RbTreeNode y = _root;
            RbTreeNode x = _root.Left;

            while (x != RbTreeNode.Nil)
            {
                y = x;
                int result = _comparer.Compare(x.Value, z.Value);

                if (!allowDuplicates && (result == 0))
                {
                    if (replaceIfDuplicate)
                    {
                        x.Value = z.Value;
                    }

                    return(new InsertResult(false, x));
                }

                if (result > 0) // x.Value > z.Value
                {
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            z.Parent = y;

            if ((y == _root) || (_comparer.Compare(y.Value, z.Value) > 0))
            {
                y.Left = z;
            }
            else
            {
                y.Right = z;
            }

            z.Parent = y;
            return(new InsertResult(true, z));
        }
예제 #18
0
        public RbTreeNode UpperBound(object val)
        {
            RbTreeNode root = this.Root;
            RbTreeNode nil  = RbTreeNode.Nil;

            while (root != RbTreeNode.Nil)
            {
                if (this._comparer.Compare(val, root.Value) < 0)
                {
                    nil  = root;
                    root = root.Left;
                }
                else
                {
                    root = root.Right;
                }
            }
            return(nil);
        }
예제 #19
0
        public ICollection FindAll(object key)
        {
            ArrayList list = new ArrayList();

            if (key != null)
            {
                RbTreeNode node  = this._tree.LowerBound(key);
                RbTreeNode node2 = this._tree.UpperBound(key);
                if (node == node2)
                {
                    return(list);
                }
                for (RbTreeNode node3 = node; node3 != node2; node3 = this._tree.Next(node3))
                {
                    list.Add(node3.Value);
                }
            }
            return(list);
        }
예제 #20
0
        /// <summary>
        /// Returns fisrt node whose value is not less than parameter.
        /// </summary>
        /// <param name="val">The value to look for.</param>
        /// <returns>The node, if found, or RbTreeNode.Nil.</returns>
        public RbTreeNode LowerBound(object val)
        {
            RbTreeNode x = Root;
            RbTreeNode y = RbTreeNode.Nil; // previous value of x

            while (x != RbTreeNode.Nil)
            {
                if (_comparer.Compare(val, x.Value) <= 0) // val <= x.Value
                {
                    y = x;
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            return(y);
        }
예제 #21
0
        /// <summary>
        /// Returns first node whose value is strictly greater than parameter.
        /// </summary>
        /// <param name="val">The value to look for.</param>
        /// <returns>The node, if found, or RbTreeNode.Nil.</returns>
        public RbTreeNode UpperBound(object val)
        {
            RbTreeNode x = Root;
            RbTreeNode y = RbTreeNode.Nil;

            while (x != RbTreeNode.Nil)
            {
                if (_comparer.Compare(val, x.Value) < 0) // val < x.Value
                {
                    y = x;
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            return(y);
        }
예제 #22
0
        private static void RightRotate(RbTreeNode y)
        {
            RbTreeNode left = y.Left;

            y.Left = left.Right;
            if (left.Right != RbTreeNode.Nil)
            {
                left.Right.Parent = y;
            }
            left.Parent = y.Parent;
            if (y == y.Parent.Left)
            {
                y.Parent.Left = left;
            }
            else
            {
                y.Parent.Right = left;
            }
            left.Right = y;
            y.Parent   = left;
        }
예제 #23
0
        private void LeftRotate(RbTreeNode x)
        {
            RbTreeNode right = x.Right;

            x.Right = right.Left;
            if (right.Left != RbTreeNode.Nil)
            {
                right.Left.Parent = x;
            }
            right.Parent = x.Parent;
            if (x == x.Parent.Left)
            {
                x.Parent.Left = right;
            }
            else
            {
                x.Parent.Right = right;
            }
            right.Left = x;
            x.Parent   = right;
        }
예제 #24
0
        private InsertResult BinaryInsert(RbTreeNode z, bool allowDuplicates, bool replaceIfDuplicate)
        {
            z.Left  = RbTreeNode.Nil;
            z.Right = RbTreeNode.Nil;
            RbTreeNode node = this._root;
            RbTreeNode left = this._root.Left;

            while (left != RbTreeNode.Nil)
            {
                node = left;
                int num = this._comparer.Compare(left.Value, z.Value);
                if (!allowDuplicates && (num == 0))
                {
                    if (replaceIfDuplicate)
                    {
                        left.Value = z.Value;
                    }
                    return(new InsertResult(false, left));
                }
                if (num > 0)
                {
                    left = left.Left;
                }
                else
                {
                    left = left.Right;
                }
            }
            z.Parent = node;
            if ((node == this._root) || (this._comparer.Compare(node.Value, z.Value) > 0))
            {
                node.Left = z;
            }
            else
            {
                node.Right = z;
            }
            z.Parent = node;
            return(new InsertResult(true, z));
        }
예제 #25
0
        /// <summary>
        /// Finds object(s) in the set.
        /// </summary>
        /// <returns>Collection of objects equal to <b>obj</b>.</returns>
        /// <remarks>
        /// If no elements equal to <b>obj</b> are found in the set, returns
        /// valid reference to an empty collection.
        /// </remarks>
        public System.Collections.ICollection FindAll(object key)
        {
            System.Collections.ArrayList result = new System.Collections.ArrayList();
            if (key == null)
            {
                return(result);
            }

            RbTreeNode lower = _tree.LowerBound(key);
            RbTreeNode upper = _tree.UpperBound(key);

            if (lower == upper)
            {
                return(result);
            }

            for (RbTreeNode node = lower; node != upper; node = _tree.Next(node))
            {
                result.Add(node.Value);
            }

            return(result);
        }
예제 #26
0
 public void Reset()
 {
     _currentNode = null;
 }
예제 #27
0
        /// <summary>
        /// Right rotation of the tree around y.
        /// </summary>
        static private void RightRotate(RbTreeNode y)
        {
            RbTreeNode x = y.Left;
            y.Left = x.Right;

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

            x.Parent = y.Parent;

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

            x.Right = y;
            y.Parent = x;
        }
예제 #28
0
        /// <summary>
        /// Left rotation of the tree around x.
        /// </summary>
        private void LeftRotate(RbTreeNode x)
        {
            RbTreeNode y = x.Right;
            x.Right = y.Left;

            if (y.Left != RbTreeNode.Nil)
                y.Left.Parent = x;

            y.Parent = x.Parent;

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

            y.Left = x;
            x.Parent = y;
        }
예제 #29
0
        private void DeleteFixUp(RbTreeNode x)
        {
            RbTreeNode root = _root.Left;

            while ((!x.IsRed) && (root != x))
            {
                if (x == x.Parent.Left)
                {
                    RbTreeNode w = x.Parent.Right;

                    if (w.IsRed)
                    {
                        w.IsRed        = false;
                        x.Parent.IsRed = true;
                        LeftRotate(x.Parent);
                        w = x.Parent.Right;
                    }

                    if ((!w.Right.IsRed) && (!w.Left.IsRed))
                    {
                        w.IsRed = true;
                        x       = x.Parent;
                    }
                    else
                    {
                        if (!w.Right.IsRed)
                        {
                            w.Left.IsRed = false;
                            w.IsRed      = true;
                            RightRotate(w);
                            w = x.Parent.Right;
                        }

                        w.IsRed        = x.Parent.IsRed;
                        x.Parent.IsRed = false;
                        w.Right.IsRed  = false;
                        LeftRotate(x.Parent);

                        x = root; /* this is to exit while loop */
                    }
                }
                else
                { /* the code below is has Left and Right switched from above */
                    RbTreeNode w = x.Parent.Left;
                    if (w.IsRed)
                    {
                        w.IsRed        = false;
                        x.Parent.IsRed = true;
                        RightRotate(x.Parent);
                        w = x.Parent.Left;
                    }
                    if ((!w.Right.IsRed) && (!w.Left.IsRed))
                    {
                        w.IsRed = true;
                        x       = x.Parent;
                    }
                    else
                    {
                        if (!w.Left.IsRed)
                        {
                            w.Right.IsRed = false;
                            w.IsRed       = true;
                            LeftRotate(w);
                            w = x.Parent.Left;
                        }
                        w.IsRed        = x.Parent.IsRed;
                        x.Parent.IsRed = false;
                        w.Left.IsRed   = false;
                        RightRotate(x.Parent);
                        x = root; /* this is to exit while loop */
                    }
                }
            }

            x.IsRed = false;
        }
예제 #30
0
 /// <summary>
 /// Creates new instance of InsertResult.
 /// </summary>
 public InsertResult(bool newNode, RbTreeNode node)
 {
     NewNode = newNode;
     Node    = node;
 }
예제 #31
0
        /// <summary>
        /// Node in the tree that follows given node.
        /// </summary>
        /// <remarks>
        /// If x is logically last node in the tree, returns RbTreeNode.Nil.
        /// </remarks>
        public RbTreeNode Next(RbTreeNode x)
        {
            RbTreeNode root = _root;
            RbTreeNode y = x.Right;

            if (y != RbTreeNode.Nil)
            {
                while (y.Left != RbTreeNode.Nil)
                { /* returns the minimum of the right subtree of x */
                    y = y.Left;
                }

                return (y);
            }
            else
            {
                y = x.Parent;

                while (x == y.Right)
                { /* sentinel used instead of checking for nil */
                    x = y;
                    y = y.Parent;
                }

                if (y == root) return (RbTreeNode.Nil);
                return (y);
            }
        }
예제 #32
0
        /// <summary>
        /// Inserts object into the tree.
        /// </summary>
        /// <param name="val">Value to insert.</param>
        ///
        /// <param name="allowDuplicates">If true, will create a new node even if equal node
        /// already exists in the tree. If false, behavior depends on replaceIfDuplicate.
        /// </param>
        ///
        /// <param name="replaceIfDuplicate">Matters only if node equal to val exists in the
        /// tree and allowDuplicates is false. If replaceIfDuplicate is true, val replaces
        /// value of existing node. Otherwise, tree does not change.
        /// </param>
        /// <returns>
        /// <list type="table">
        /// <item><term>result.NewNode</term><description>true if new node was inserted to the tree</description></item>
        /// <item><term>result.Node</term><description>contains newly inserted node if any, or node equal to val</description> </item>
        /// </list>
        /// </returns>
        public InsertResult Insert(object val, bool allowDuplicates, bool replaceIfDuplicate)
        {
            RbTreeNode   newNode = new RbTreeNode(val);
            InsertResult result  = BinaryInsert(newNode, allowDuplicates, replaceIfDuplicate);

            if (!result.NewNode)
            {
                return(result);
            }

            RbTreeNode x = newNode;

            x.IsRed = true;

            while (x.Parent.IsRed)
            {
                if (x.Parent == x.Parent.Parent.Left)
                {
                    RbTreeNode y = x.Parent.Parent.Right;

                    if (y.IsRed)
                    {
                        x.Parent.IsRed        = false;
                        y.IsRed               = false;
                        x.Parent.Parent.IsRed = true;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Right)
                        {
                            x = x.Parent;
                            LeftRotate(x);
                        }

                        x.Parent.IsRed        = false;
                        x.Parent.Parent.IsRed = true;
                        RightRotate(x.Parent.Parent);
                    }
                }
                else
                { /* case for x.Parent == x.Parent.Parent.Right */
                    RbTreeNode y = x.Parent.Parent.Left;

                    if (y.IsRed)
                    {
                        x.Parent.IsRed        = false;
                        y.IsRed               = false;
                        x.Parent.Parent.IsRed = true;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RightRotate(x);
                        }
                        x.Parent.IsRed        = false;
                        x.Parent.Parent.IsRed = true;
                        LeftRotate(x.Parent.Parent);
                    }
                }
            }

            _root.Left.IsRed = false;

            return(new InsertResult(true, newNode));
        }
예제 #33
0
        /// <summary>
        /// Removes node from the tree, re-arranging red-black structure as needed.
        /// </summary>
        public void Erase(RbTreeNode z)
        {
            RbTreeNode y;
            RbTreeNode x;
            RbTreeNode root = _root;

            if ((z.Left == RbTreeNode.Nil) || (z.Right == RbTreeNode.Nil))
            {
                y = z;
            }
            else
            {
                y = Next(z);
            }

            x = (y.Left == RbTreeNode.Nil) ? y.Right : y.Left;
            if (_root == (x.Parent = y.Parent))  /* assignment of y.p to x.p is intentional */
            {
                _root.Left = x;
            }
            else
            {
                if (y == y.Parent.Left)
                {
                    y.Parent.Left = x;
                }
                else
                {
                    y.Parent.Right = x;
                }
            }

            if (!(y.IsRed))
                DeleteFixUp(x);

            if (y != z)
            {
                y.Left = z.Left;
                y.Right = z.Right;
                y.Parent = z.Parent;
                y.IsRed = z.IsRed;
                z.Left.Parent = z.Right.Parent = y;

                if (z == z.Parent.Left)
                {
                    z.Parent.Left = y;
                }
                else
                {
                    z.Parent.Right = y;
                }
            }

            IDisposable zVal = z.Value as IDisposable;
            if (zVal != null)
                zVal.Dispose();
        }
예제 #34
0
        /// <summary>
        /// Node in the tree that precedes given node.
        /// </summary>
        /// <remarks>
        /// If x is logically fisrt node, returns RbTreeNode.Nil.
        /// </remarks>
        public RbTreeNode Prev(RbTreeNode x)
        {
            RbTreeNode root = _root;
            RbTreeNode y = x.Left;


            if (y != RbTreeNode.Nil)
            {
                while (y.Right != RbTreeNode.Nil)
                { /* returns the maximum of the left subtree of x */
                    y = y.Right;
                }
                return (y);
            }
            else
            {
                y = x.Parent;
                while (x == y.Left)
                {
                    if (y == root) return RbTreeNode.Nil;
                    x = y;
                    y = y.Parent;
                }
                return (y);
            }
        }
예제 #35
0
        private void DeleteFixUp(RbTreeNode x)
        {
            RbTreeNode left = this._root.Left;

            while (!x.IsRed && (left != x))
            {
                RbTreeNode right;
                if (x == x.Parent.Left)
                {
                    right = x.Parent.Right;
                    if (right.IsRed)
                    {
                        right.IsRed    = false;
                        x.Parent.IsRed = true;
                        this.LeftRotate(x.Parent);
                        right = x.Parent.Right;
                    }
                    if (!(right.Right.IsRed || right.Left.IsRed))
                    {
                        right.IsRed = true;
                        x           = x.Parent;
                    }
                    else
                    {
                        if (!right.Right.IsRed)
                        {
                            right.Left.IsRed = false;
                            right.IsRed      = true;
                            RightRotate(right);
                            right = x.Parent.Right;
                        }
                        right.IsRed       = x.Parent.IsRed;
                        x.Parent.IsRed    = false;
                        right.Right.IsRed = false;
                        this.LeftRotate(x.Parent);
                        x = left;
                    }
                }
                else
                {
                    right = x.Parent.Left;
                    if (right.IsRed)
                    {
                        right.IsRed    = false;
                        x.Parent.IsRed = true;
                        RightRotate(x.Parent);
                        right = x.Parent.Left;
                    }
                    if (!(right.Right.IsRed || right.Left.IsRed))
                    {
                        right.IsRed = true;
                        x           = x.Parent;
                    }
                    else
                    {
                        if (!right.Left.IsRed)
                        {
                            right.Right.IsRed = false;
                            right.IsRed       = true;
                            this.LeftRotate(right);
                            right = x.Parent.Left;
                        }
                        right.IsRed      = x.Parent.IsRed;
                        x.Parent.IsRed   = false;
                        right.Left.IsRed = false;
                        RightRotate(x.Parent);
                        x = left;
                    }
                }
            }
            x.IsRed = false;
        }
예제 #36
0
        /// <summary>
        /// Inserts item based only on its value, probably violating Left/Right property.
        /// </summary>
        /// <param name="z">Node to insert.</param>
        /// 
        /// <param name="allowDuplicates">If true, will insert the node even if equal node 
        /// already exists in the tree. If false, behavior depends on replaceIfDuplicate.
        /// </param>
        /// 
        /// <param name="replaceIfDuplicate">Matters only if node equal to z exists in the 
        /// tree and allowDuplicates is false. If replaceIfDuplicate is true, z replaces
        /// existing node. Otherwise, tree does not change.
        /// </param>
        /// <returns>
        /// result.NewNode is true if new node was inserted to the tree'
        /// result.Node contains newly inserted node if any, or node equal to z
        /// </returns>
        /// 
        private InsertResult BinaryInsert(RbTreeNode z, bool allowDuplicates, bool replaceIfDuplicate)
        {
            z.Left = RbTreeNode.Nil;
            z.Right = RbTreeNode.Nil;

            RbTreeNode y = _root;
            RbTreeNode x = _root.Left;

            while (x != RbTreeNode.Nil)
            {
                y = x;
                int result = _comparer.Compare(x.Value, z.Value);

                if (!allowDuplicates && (result == 0))
                {
                    if (replaceIfDuplicate)
                    {
                        x.Value = z.Value;
                    }

                    return new InsertResult(false, x);
                }

                if (result > 0) // x.Value > z.Value
                {
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            z.Parent = y;

            if ((y == _root) || (_comparer.Compare(y.Value, z.Value) > 0))
            {
                y.Left = z;
            }
            else
            {
                y.Right = z;
            }

            z.Parent = y;
            return new InsertResult(true, z);
        }
예제 #37
0
        /// <summary>
        /// Removes node from the tree, re-arranging red-black structure as needed.
        /// </summary>
        public void Erase(RbTreeNode z)
        {
            RbTreeNode y;
            RbTreeNode x;
            RbTreeNode root = _root;

            if ((z.Left == RbTreeNode.Nil) || (z.Right == RbTreeNode.Nil))
            {
                y = z;
            }
            else
            {
                y = Next(z);
            }

            x = (y.Left == RbTreeNode.Nil) ? y.Right : y.Left;
            if (_root == (x.Parent = y.Parent))  /* assignment of y.p to x.p is intentional */
            {
                _root.Left = x;
            }
            else
            {
                if (y == y.Parent.Left)
                {
                    y.Parent.Left = x;
                }
                else
                {
                    y.Parent.Right = x;
                }
            }

            if (!(y.IsRed))
            {
                DeleteFixUp(x);
            }

            if (y != z)
            {
                y.Left        = z.Left;
                y.Right       = z.Right;
                y.Parent      = z.Parent;
                y.IsRed       = z.IsRed;
                z.Left.Parent = z.Right.Parent = y;

                if (z == z.Parent.Left)
                {
                    z.Parent.Left = y;
                }
                else
                {
                    z.Parent.Right = y;
                }
            }

            IDisposable zVal = z.Value as IDisposable;

            if (zVal != null)
            {
                zVal.Dispose();
            }
        }
예제 #38
0
 /// <summary>
 /// Creates a new instance of a red-black tree.
 /// </summary>
 public RbTree(IComparer comparer)
 {
     _root = new RbTreeNode(null);
     _root.IsRed = false;
     _comparer = comparer;
 }
예제 #39
0
 /// <summary>
 /// Creates new instance of InsertResult.
 /// </summary>
 public InsertResult(bool newNode, RbTreeNode node)
 {
     NewNode = newNode;
     Node = node;
 }
예제 #40
0
        /// <summary>
        /// Inserts object into the tree.
        /// </summary>
        /// <param name="val">Value to insert.</param>
        /// 
        /// <param name="allowDuplicates">If true, will create a new node even if equal node 
        /// already exists in the tree. If false, behavior depends on replaceIfDuplicate.
        /// </param>
        /// 
        /// <param name="replaceIfDuplicate">Matters only if node equal to val exists in the 
        /// tree and allowDuplicates is false. If replaceIfDuplicate is true, val replaces
        /// value of existing node. Otherwise, tree does not change.
        /// </param>
        /// <returns>
        /// <list type="table">
        /// <item><term>result.NewNode</term><description>true if new node was inserted to the tree</description></item>
        /// <item><term>result.Node</term><description>contains newly inserted node if any, or node equal to val</description> </item>
        /// </list>
        /// </returns>
        public InsertResult Insert(object val, bool allowDuplicates, bool replaceIfDuplicate)
        {
            RbTreeNode newNode = new RbTreeNode(val);
            InsertResult result = BinaryInsert(newNode, allowDuplicates, replaceIfDuplicate);

            if (!result.NewNode) return result;

            RbTreeNode x = newNode;
            x.IsRed = true;

            while (x.Parent.IsRed)
            {
                if (x.Parent == x.Parent.Parent.Left)
                {
                    RbTreeNode y = x.Parent.Parent.Right;

                    if (y.IsRed)
                    {
                        x.Parent.IsRed = false;
                        y.IsRed = false;
                        x.Parent.Parent.IsRed = true;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Right)
                        {
                            x = x.Parent;
                            LeftRotate(x);
                        }

                        x.Parent.IsRed = false;
                        x.Parent.Parent.IsRed = true;
                        RightRotate(x.Parent.Parent);
                    }
                }
                else
                { /* case for x.Parent == x.Parent.Parent.Right */
                    RbTreeNode y = x.Parent.Parent.Left;

                    if (y.IsRed)
                    {
                        x.Parent.IsRed = false;
                        y.IsRed = false;
                        x.Parent.Parent.IsRed = true;
                        x = x.Parent.Parent;
                    }
                    else
                    {
                        if (x == x.Parent.Left)
                        {
                            x = x.Parent;
                            RightRotate(x);
                        }
                        x.Parent.IsRed = false;
                        x.Parent.Parent.IsRed = true;
                        LeftRotate(x.Parent.Parent);
                    }
                }
            }

            _root.Left.IsRed = false;

            return new InsertResult(true, newNode);
        }
예제 #41
0
 public void Reset()
 {
     _currentNode = null;
 }
예제 #42
0
 /// <summary>
 /// Creates a new instance of a red-black tree.
 /// </summary>
 public RbTree(IComparer comparer)
 {
     _root       = new RbTreeNode(null);
     _root.IsRed = false;
     _comparer   = comparer;
 }
예제 #43
0
        private void DeleteFixUp(RbTreeNode x)
        {
            RbTreeNode root = _root.Left;

            while ((!x.IsRed) && (root != x))
            {
                if (x == x.Parent.Left)
                {
                    RbTreeNode w = x.Parent.Right;

                    if (w.IsRed)
                    {
                        w.IsRed = false;
                        x.Parent.IsRed = true;
                        LeftRotate(x.Parent);
                        w = x.Parent.Right;
                    }

                    if ((!w.Right.IsRed) && (!w.Left.IsRed))
                    {
                        w.IsRed = true;
                        x = x.Parent;
                    }
                    else
                    {
                        if (!w.Right.IsRed)
                        {
                            w.Left.IsRed = false;
                            w.IsRed = true;
                            RightRotate(w);
                            w = x.Parent.Right;
                        }

                        w.IsRed = x.Parent.IsRed;
                        x.Parent.IsRed = false;
                        w.Right.IsRed = false;
                        LeftRotate(x.Parent);

                        x = root; /* this is to exit while loop */
                    }
                }
                else
                { /* the code below is has Left and Right switched from above */
                    RbTreeNode w = x.Parent.Left;
                    if (w.IsRed)
                    {
                        w.IsRed = false;
                        x.Parent.IsRed = true;
                        RightRotate(x.Parent);
                        w = x.Parent.Left;
                    }
                    if ((!w.Right.IsRed) && (!w.Left.IsRed))
                    {
                        w.IsRed = true;
                        x = x.Parent;
                    }
                    else
                    {
                        if (!w.Left.IsRed)
                        {
                            w.Right.IsRed = false;
                            w.IsRed = true;
                            LeftRotate(w);
                            w = x.Parent.Left;
                        }
                        w.IsRed = x.Parent.IsRed;
                        x.Parent.IsRed = false;
                        w.Left.IsRed = false;
                        RightRotate(x.Parent);
                        x = root; /* this is to exit while loop */
                    }
                }
            }

            x.IsRed = false;
        }