public void AssertValidTree() { if (this.Root != null) { RedBlackNode <T> previousNode = null; foreach (RedBlackNode <T> node in this.InOrderNodeIterator) { if (previousNode != null && previousNode.Value.CompareTo(node.Value) >= 0) { throw new InvalidTreeException(); } previousNode = node; } } int numBlack; AssertValidTree(this.Root as RedBlackNode <T>, out numBlack); }
public bool Contains(T item) { RedBlackNode <T> current = this.Root; while (current != null) { int compareResult = current.Value.CompareTo(item); if (compareResult == 0) { break; } else if (compareResult > 0) { current = current.Left; } else { current = current.Right; } } return(current != null); }
private static void AssertValidTree(RedBlackNode <T> root, out int numBlack) { if (root == null) { numBlack = 0; } else { if (IsNodeRed(root)) { if (IsNodeRed(root.Left) || IsNodeRed(root.Right)) { throw new InvalidTreeException(); } } int leftBlack; int rightBlack; AssertValidTree(root.Left, out leftBlack); AssertValidTree(root.Right, out rightBlack); if (leftBlack != rightBlack) { throw new InvalidTreeException(); } if (IsNodeRed(root)) { numBlack = leftBlack; } else { numBlack = leftBlack + 1; } } }
/// <summary> /// Inserts the given node underneath the given root according to the BinarySearchTree algorithm and then /// rebalances the tree according to the red-black tree rules /// </summary> /// <param name="root">The root node of the tree</param> /// <param name="node">The node to insert</param> /// <returns>The new root of the tree as it may have changed</returns> private RedBlackNode <T> Insert(RedBlackNode <T> root, RedBlackNode <T> node) { if (root == null) { root = node; ++this.Count; } else { root.ResetHeight(); int compareResult = root.Value.CompareTo(node.Value); if (compareResult > 0) { root.Left = Insert(root.Left, node); } else if (compareResult < 0) { root.Right = Insert(root.Right, node); } else { throw new ArgumentException(Resources.Errors.InsertDuplicate); } } if (root.Value.CompareTo(node.Value) > 0) { root = Insert_Case1_LeftTwoRedChidren(root as RedBlackNode <T>); } else { root = Insert_Case1_RightTwoRedChidren(root as RedBlackNode <T>); } return(root); }
private int GetChildNodeHeight(RedBlackNode <T> node) { return((node == null) ? -1 : node.Height); }
/// <summary> /// Moves a black root node down to it's two children and colours the root red /// </summary> /// <param name="root"></param> private static void MoveBlackDown(RedBlackNode <T> root) { root.SetColour(Colour.Red); root.Left.SetColour(Colour.Black); root.Right.SetColour(Colour.Black); }
/// <summary> /// Returns true if the node is red. Returns false if the node is black or null. /// </summary> private static bool IsNodeRed(RedBlackNode <T> node) { return(node != null && node.IsRed); }
/// <summary> /// Deletes the given value from the tree at the given root and ensures red-black tree properties are maintained ny recolouring nodes and rotations /// </summary> /// <param name="root">The root node of the tree</param> /// <param name="value">The value to delete</param> /// <param name="done">A flag determining if more rebalancing and recolouring is necessary</param> /// <returns>The new root of the tree as it may have changed</returns> private RedBlackNode <T> Delete(RedBlackNode <T> root, T value, ref bool done) { int compareResult = root.Value.CompareTo(value); if (compareResult == 0) { // Node has two children, replace with in order predecessor and then recursively delete predecessor if (root.Left != null && root.Right != null) { compareResult = 1; root.Value = root.InOrderPredecessor.Value; value = root.Value; root.ResetHeight(); } // Node only has left child else if (root.Left != null) { --this.Count; root.Left.ResetHeight(); if (IsNodeRed(root.Left)) // node to delete is black but has red child that can be recoloured { root.Left.SetColour(Colour.Black); done = true; } root = root.Left; } // Node only has Right child else if (root.Right != null) { --this.Count; root.Right.ResetHeight(); if (IsNodeRed(root.Right)) // node to delete is black but has red child that can be recoloured { root.Right.SetColour(Colour.Black); done = true; } root = root.Right; } else // deleting leaf - done if red { --this.Count; done = IsNodeRed(root); root = null; } } if (compareResult > 0) { if (root.Left != null) { root.Left = Delete(root.Left, value, ref done); if (!done) { root = this.DeleteRebalanceLeft(root, ref done); } } else { throw new ValueNotFoundException(); } } else if (compareResult < 0) { if (root.Right != null) { root.Right = Delete(root.Right, value, ref done); if (!done) { root = this.DeleteRebalanceRight(root, ref done); } } else { throw new ValueNotFoundException(); } } return(root); }