/// <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; }
/// <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; }
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); }
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); }
/// <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); } }
/// <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); } }
/// <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; }
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; }
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(); } }
public bool MoveNext() { if (this._currentNode == null) { this._currentNode = this._tree.First; } else { this._currentNode = this._tree.Next(this._currentNode); } return(!this._currentNode.IsNull); }
public bool MoveNext() { if (_currentNode == null) { _currentNode = _tree.First; } else { _currentNode = _tree.Next(_currentNode); } return !_currentNode.IsNull; }
public bool MoveNext() { if (_currentNode == null) { _currentNode = _tree.First; } else { _currentNode = _tree.Next(_currentNode); } return(!_currentNode.IsNull); }
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); }
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); }
/// <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); }
/// <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)); }
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); }
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); }
/// <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); }
/// <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); }
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; }
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; }
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)); }
/// <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); }
public void Reset() { _currentNode = null; }
/// <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; }
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; }
/// <summary> /// Creates new instance of InsertResult. /// </summary> public InsertResult(bool newNode, RbTreeNode node) { NewNode = newNode; Node = node; }
/// <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); } }
/// <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)); }
/// <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(); }
/// <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); } }
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; }
/// <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); }
/// <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(); } }
/// <summary> /// Creates a new instance of a red-black tree. /// </summary> public RbTree(IComparer comparer) { _root = new RbTreeNode(null); _root.IsRed = false; _comparer = comparer; }
/// <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); }