/// <summary> /// Rotates the tree rooted at this node in a clockwise manner and recolours the root and pivot nodes accordingly. /// </summary> /// <returns>The new root of the tree</returns> internal RedBlackNode <T> RotateRight() { RedBlackNode <T> pivot = this.Left; this.Left = pivot.Right; pivot.Right = this; //fix heights pivot.ResetHeight(); this.ResetHeight(); pivot.Right.SetColour(Colour.Red); pivot.SetColour(Colour.Black); return(pivot); }
/// <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); }