Ejemplo n.º 1
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);
            }
        }
Ejemplo n.º 2
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);
            }
        }
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
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;
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Finds object in the set.
        /// </summary>
        /// <returns>First object equal to <b>obj</b>, or null if not found.</returns>
        public object Find(object key)
        {
            if (key == null)
            {
                return(null);
            }
            RbTreeNode node = _tree.LowerBound(key);

            if (node.IsNull)
            {
                return(null);
            }

            if (Comparer.Compare(node.Value, key) == 0)
            {
                return(node.Value);
            }
            return(null);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
		}
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
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);
		}
Ejemplo n.º 13
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;
 }
Ejemplo n.º 14
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();
            }
        }
Ejemplo n.º 15
0
			/// <summary>
			/// Creates new instance of InsertResult.
			/// </summary>
			public InsertResult(bool newNode, RbTreeNode node) {
				NewNode = newNode;
				Node = node;
			}
Ejemplo n.º 16
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;
		}
Ejemplo n.º 17
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);
			}
		}
Ejemplo n.º 18
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();
		}
Ejemplo n.º 19
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;
		}
Ejemplo n.º 20
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);
			}
		}
Ejemplo n.º 21
0
 /// <summary>
 /// Creates new instance of InsertResult.
 /// </summary>
 public InsertResult(bool newNode, RbTreeNode node)
 {
     NewNode = newNode;
     Node    = node;
 }
Ejemplo n.º 22
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;
		}
Ejemplo n.º 23
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;
		}
Ejemplo n.º 24
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));
        }
Ejemplo n.º 25
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;
        }