/// <summary> /// Sets the enumerator the its initial position which is before /// the first element of the RedBlackTree. /// </summary> public void Reset() { if(!isValid) throw new InvalidOperationException("The RedBlackTree was modified after the enumerator was created"); started = false; current = tree.root; if(current != null) { while(current.Left != null) current = current.Left; } }
/// <summary> /// Initializes an new instance of Collections.System.RedBlackTreeNode /// class. All references are set to null. /// </summary> internal RedBlackTreeNode() { key = null; father = null; left = null; right = null; color = true; }
/// <summary> /// Initializes an new instance of Collections.System.RedBlackTreeEnumerator /// class. The current position is before the first element. /// </summary> /// <param name="t">The RedBlackTree which will be enumerate.</param> internal RedBlackTreeEnumerator(RedBlackTree t) { tree = t; started = false; isValid = true; current = tree.root; if(current != null) { while(current.Left != null) current = current.Left; } }
/// <summary> /// Advances the RedBlackTreeEnumerator the next element of the RedBlackTree. /// Returns whether the move was possible. /// </summary> public bool MoveNext() { if(!isValid) throw new InvalidOperationException("The RedBlackTree was modified after the enumerator was created"); if(!started) { started = true; return current != null; } if(current == null) return false; if(current.Right == null) { RedBlackTreeNode prev; do { prev = current; current = current.Father; } while((current != null) && (current.Right == prev)); } else { current = current.Right; while(current.Left != null) current = current.Left; } return current != null; }
/// <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 RedBlackTreeNode RecContains(RedBlackTreeNode node, object 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); }
/// <summary> /// For debugging only. Checks whether the RedBlackTree is conform /// to the definition of the a red-black tree. If not an /// exception is thrown. /// </summary> /// <param name="node">The root of the tree.</param> private int RecConform(RedBlackTreeNode node) { if(node == null) return 1; if(node.Father == null) { if(node.Color) throw new ArgumentException("RedBlackTree : the root is not black."); } else { if(node.Father.Color && node.Color) throw new ArgumentException("RedBlackTree : father and son are red."); } if(node.Left != null && comparer.Compare(node.Key, node.Left.Key) < 0) throw new ArgumentException("RedBlackTree : order not respected in tree."); if(node.Right != null && comparer.Compare(node.Key, node.Right.Key) > 0) throw new ArgumentException("RedBlackTree : order not respected in tree."); int a = RecConform(node.Left), b = RecConform(node.Right); if(a < 0 || b < 0) return -1; if(a != b) throw new ArgumentException("RedBlackTree : the paths do have not the same number of black nodes."); if(!node.Color) return (a+1); else return a; }
/// <summary> /// Performs a right tree rotation. /// </summary> /// <param name="node"> /// node is considered as the root of the tree.</param> private void RotateRight(RedBlackTreeNode node) { RedBlackTreeNode nodeX = node, nodeY = node.Left; nodeX.Left = nodeY.Right; if(nodeY.Right != null) nodeY.Right.Father = nodeX; nodeY.Father = nodeX.Father; if(nodeX.Father == null) root = nodeY; else { if(nodeX == nodeX.Father.Right) nodeX.Father.Right = nodeY; else nodeX.Father.Left = nodeY; } nodeY.Right = nodeX; nodeX.Father = nodeY; }
/// <summary> /// Removes a specific node of the RedBlackTree. /// </summary> /// <param name="node"> /// node must be contained by RedBlackTree.</param> private void RemoveRedBlackTreeNode(RedBlackTreeNode node) { RedBlackTreeNode 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> /// Removes a specific node of the RedBlackTree. /// </summary> /// <param name="node"> /// node must be contained by RedBlackTree.</param> private void RemoveRedBlackTreeNode(RedBlackTreeNode node) { RedBlackTreeNode 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> /// 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 RedBlackTree.</param> private RedBlackTreeNode Successor(RedBlackTreeNode node) { RedBlackTreeNode 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 of the elements from the RedBlackTree. /// </summary> public void Clear() { rwLock.AcquireWriterLock(Timeout.Infinite); try { OnRedBlackTreeModified(); root = null; count = 0; } finally { rwLock.ReleaseWriterLock(); } }
/// <summary> /// Adds an elements to the RedBlackTree. The operation is performed /// in a guaranteed logarithmic time of the RedBlackTree size. /// </summary> public void Add(object x) { rwLock.AcquireReaderLock(Timeout.Infinite); try { OnRedBlackTreeModified(); //if(comparer == null) // throw new ArgumentException("RedBlackTree : not able to compare the elements"); if(root == null) root = new RedBlackTreeNode(x, null); else { // First step : a naive insertion of the element RedBlackTreeNode node1 = root, node2 = null; while(node1 != null) { node2 = node1; if(comparer.Compare(x,node1.Key) < 0) node1 = node1.Left; else node1 = node1.Right; } node1 = new RedBlackTreeNode(x, node2); if(comparer.Compare(x,node2.Key) < 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); } } } } root.Color = false; count++; } finally { rwLock.ReleaseReaderLock(); } }
/// <summary> /// Perform the common initialization taks to all the constructors. /// </summary> private void Initialize() { count = 0; root = null; rwLock = new ReaderWriterLock(); }
/// <summary> /// Initializes an new instance of Collections.System.RedBlackTreeNode /// class and partially insert the RedBlackTreeNode into a tree. /// </summary> /// <param name="k">Key of the RedBlackTreeNode</param> /// <param name="fatherRedBlackTreeNode">The father node of the instanciated RedBlackTreeNode.</param> internal RedBlackTreeNode(object k, RedBlackTreeNode fatherRedBlackTreeNode) { key = k; father = fatherRedBlackTreeNode; left = null; right = null; color = true; }
/// <summary> /// Copies the element of the tree into a one dimensional /// System.Array starting at index. /// </summary> /// <param name="currentRedBlackTreeNode">The root of the tree.</param> /// <param name="array">The System.Array where the elements will be copied.</param> /// <param name="index">The index where the copy will start.</param> /// <returns> /// The new index after the copy of the elements of the tree. /// </returns> private int RecCopyTo(RedBlackTreeNode currentRedBlackTreeNode, Array array, int index) { if(currentRedBlackTreeNode != null) { array.SetValue(currentRedBlackTreeNode.Key, index); return RecCopyTo(currentRedBlackTreeNode.Right, array, RecCopyTo(currentRedBlackTreeNode.Left, array, index + 1)); } else return index; }
/// <summary> /// Adds an elements to the RedBlackTree. The operation is performed /// in a guaranteed logarithmic time of the RedBlackTree size. /// </summary> public void Add(object x) { rwLock.AcquireReaderLock(Timeout.Infinite); try { OnRedBlackTreeModified(); //if(comparer == null) // throw new ArgumentException("RedBlackTree : not able to compare the elements"); if (root == null) { root = new RedBlackTreeNode(x, null); } else { // First step : a naive insertion of the element RedBlackTreeNode node1 = root, node2 = null; while (node1 != null) { node2 = node1; if (comparer.Compare(x, node1.Key) < 0) { node1 = node1.Left; } else { node1 = node1.Right; } } node1 = new RedBlackTreeNode(x, node2); if (comparer.Compare(x, node2.Key) < 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); } } } } root.Color = false; count++; } finally { rwLock.ReleaseReaderLock(); } }