// copy entire subtree, recursively private RBTreeNode <T> Copy(RBTreeNode <T> oldRoot, RBTreeNode <T> newFather) { RBTreeNode <T> newRoot = null; // copy a node, then any subtrees if (oldRoot != null) { newRoot = new RBTreeNode <T>(oldRoot); if (newFather != null) { newRoot.Father = newFather; } newRoot.Left = Copy(oldRoot.Left, newRoot); newRoot.Right = Copy(oldRoot.Right, newRoot); } return(newRoot); // return newly constructed tree }
private RBTreeNode <T> UpperBoundNode(T x) { RBTreeNode <T> node = root; RBTreeNode <T> upperBoundNode = null; while (node != null) { if (comparer.Compare(x, node.Key) < 0) { // node greater than x, remember it upperBoundNode = node; node = node.Left; // descend left subtree } else { node = node.Right; // descend right subtree } } return(upperBoundNode); // return best remembered candidate }
/// <summary> /// Removes the first occurrence of the element in the RBTree. /// The operation is performed in a guaranteed logarithmic time /// of the RBTree size. /// </summary> public bool Remove(T x) { //rwLock.AcquireWriterLock( Timeout.Infinite ); try { RBTreeNode <T> node = FindNode(x); if (node != null) { RemoveRBTreeNode(node); //if( Count != EnumeratedCount ) throw new InvalidOperationException( "EnumeratedCount does not match stored count" ); return(true); } else { return(false); } } finally { //rwLock.ReleaseWriterLock(); } }
/// <summary> /// Returns a node of the tree which contains the object /// as Key. If the tree does not contain such node, then /// null is returned. /// </summary> /// <param name="node">The root of the tree.</param> /// <param name="x">The researched object.</param> private RBTreeNode <T> RecContains(RBTreeNode <T> node, T x) { if (node == null) { return(null); } int c = comparer.Compare(x, node.Key); if (c == 0) { return(node); } if (c < 0) { return(RecContains(node.Left, x)); } else { return(RecContains(node.Right, x)); } }
private RBTreeNode <T> LowerBoundNode(T x) { RBTreeNode <T> node = root; RBTreeNode <T> lowerBoundNode = null; int compare; while (node != null) { compare = comparer.Compare(node.Key, x); if (compare < 0) { node = node.Right; // descend right subtree } else { // node not less than x, remember it lowerBoundNode = node; node = node.Left; // descend left subtree } } return(lowerBoundNode); // return best remembered candidate }
/// <summary> /// Returns the node that contains the successor of node.Key. /// If such node does not exist then null is returned. /// </summary> /// <param name="node"> /// node must be contained by RBTree.</param> private RBTreeNode <T> Successor(RBTreeNode <T> node) { RBTreeNode <T> node1, node2; if (node.Right != null) { // We find the Min node1 = node.Right; while (node1.Left != null) { node1 = node1.Left; } return(node1); } node1 = node; node2 = node.Father; while (node2 != null && node1 == node2.Right) { node1 = node2; node2 = node2.Father; } return(node2); }
/// <summary> /// Removes a specific node of the RBTree. /// </summary> /// <param name="node"> /// node must be contained by RBTree.</param> private void RemoveRBTreeNode(RBTreeNode <T> node) { RBTreeNode <T> nodeX, nodeY, fatherX, fatherY; if (node.Left == null || node.Right == null) { nodeY = node; } else { nodeY = Successor(node); } if (nodeY.Left != null) { nodeX = nodeY.Left; } else { nodeX = nodeY.Right; } fatherY = nodeY.Father; fatherX = fatherY; if (nodeX != null) { nodeX.Father = nodeY.Father; } if (fatherY == null) { root = nodeX; } else { if (nodeY == fatherY.Left) { fatherY.Left = nodeX; } else { fatherY.Right = nodeX; } } if (nodeY != node) { node.Key = nodeY.Key; } // Remove Correction of the colors if (nodeY == null || !nodeY.Color) { while (nodeX != root && (nodeX == null || !nodeX.Color)) { if (nodeX == fatherX.Left /*&& nodeX != fatherX.Right*/) { fatherY = fatherX; nodeY = fatherX.Right; if (/*nodeY != null && */ nodeY.Color) { nodeY.Color = false; fatherX.Color = true; RotateLeft(fatherX); nodeY = fatherX.Right; } if ((nodeY.Left == null || !nodeY.Left.Color) && (nodeY.Right == null || !nodeY.Right.Color)) { nodeY.Color = true; nodeX = fatherX; fatherX = fatherX.Father; } else { if (nodeY.Right == null || !nodeY.Right.Color) { nodeY.Left.Color = false; nodeY.Color = true; RotateRight(nodeY); nodeY = fatherX.Right; } nodeY.Color = fatherX.Color; fatherX.Color = false; nodeY.Right.Color = false; RotateLeft(fatherX); nodeX = root; } } else { fatherY = fatherX; nodeY = fatherX.Left; if (/*nodeY != null &&*/ nodeY.Color) { nodeY.Color = false; fatherX.Color = true; RotateRight(fatherX); nodeY = fatherX.Left; } if ((nodeY.Right == null || !nodeY.Right.Color) && (nodeY.Left == null || !nodeY.Left.Color)) { nodeY.Color = true; nodeX = fatherX; fatherX = fatherX.Father; } else { if (nodeY.Left == null || !nodeY.Left.Color) { nodeY.Right.Color = false; nodeY.Color = true; RotateLeft(nodeY); nodeY = fatherX.Left; } nodeY.Color = fatherX.Color; fatherX.Color = false; nodeY.Left.Color = false; RotateRight(fatherX); nodeX = root; } } } // End While if (nodeX != null) { nodeX.Color = false; } } // End Correction count--; }
/// <summary> /// Inserts an elements to the RBTree. The operation is performed /// in a guaranteed logarithmic time of the RBTree size. /// Returns a pair: first element is a reference to either the inserted key-value pair or the existing one, /// second element is a boolean storing whether the insert actually happened /// (if the keys must be unique and the key was already in the tree, the key is not actually inserted) /// </summary> public InsertResult Insert(T x) { //rwLock.AcquireReaderLock( Timeout.Infinite ); InsertResult rv = null; try { //OnRBTreeModified(); //if(comparer == null) // throw new ArgumentException("RBTree : not able to compare the elements"); if (root == null) { root = new RBTreeNode <T>(x, null); rv = new InsertResult(root.Key, true); } else { // First step : a naive insertion of the element RBTreeNode <T> node1 = root, node2 = null; int compare = 0; while (node1 != null) { node2 = node1; compare = comparer.Compare(x, node1.Key); if (compare < 0) { node1 = node1.Left; } else if (compare > 0) { node1 = node1.Right; } else { rv = new InsertResult(node1.Key, false); node1 = null; } } if (rv == null) { node1 = new RBTreeNode <T>(x, node2); rv = new InsertResult(node1.Key, true); if (compare < 0) { node2.Left = node1; } else { node2.Right = node1; } node1.Color = true; // Then : correct the structure of the tree while (node1 != root && node1.Father.Color) { if (node1.Father == node1.Father.Father.Left) { node2 = node1.Father.Father.Right; if (node2 != null && node2.Color) { node1.Father.Color = false; node2.Color = false; node1.Father.Father.Color = true; node1 = node1.Father.Father; } else { if (node1 == node1.Father.Right) { node1 = node1.Father; RotateLeft(node1); } node1.Father.Color = false; node1.Father.Father.Color = true; RotateRight(node1.Father.Father); } } else { node2 = node1.Father.Father.Left; if (node2 != null && node2.Color) { node1.Father.Color = false; node2.Color = false; node1.Father.Father.Color = true; node1 = node1.Father.Father; } else { if (node1 == node1.Father.Left) { node1 = node1.Father; RotateRight(node1); } node1.Father.Color = false; node1.Father.Father.Color = true; RotateLeft(node1.Father.Father); } } } } else if (rv.WasInserted) { rv = new InsertResult(x, true); } } if (rv.WasInserted) { root.Color = false; count++; } } finally { //rwLock.ReleaseReaderLock(); } //if( Count != EnumeratedCount ) throw new InvalidOperationException( "EnumeratedCount does not match stored count" ); return(rv); }
private void Copy(RBTree <T> otherTree) { root = Copy(otherTree.root, root); count = otherTree.count; }
/// <summary> /// Perform the common initialization tasks to all the constructors. /// </summary> private void Initialize() { count = 0; root = null; //rwLock = new ReaderWriterLock(); }