public void AssertValidTree() { if (Root != null) { RedBlackNode <T> previousNode = null; foreach (var node in InOrderNodeIterator) { if (previousNode != null && previousNode.Value.CompareTo(node.Value) >= 0) { throw new MeshNavException("Invalid Red Black Tree"); } previousNode = node; } } AssertValidTree(Root, out _); }
/// <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.SetColor(Color.Red); root.Left.SetColor(Color.Black); root.Right.SetColor(Color.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) { var compareResult = root.Value.CompareTo(value); if (compareResult == 0) { 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) { --Count; root.Left.ResetHeight(); if (IsNodeRed(root.Left)) // node to delete is black but has red child that can be recoloured { root.Left.SetColor(Color.Black); done = true; } root = root.Left; } // Node only has Right child else if (root.Right != null) { --Count; root.Right.ResetHeight(); if (IsNodeRed(root.Right)) // node to delete is black but has red child that can be recoloured { root.Right.SetColor(Color.Black); done = true; } root = root.Right; } else // deleting leaf - done if red { --Count; done = IsNodeRed(root); root = null; } } // ReSharper disable PossibleNullReferenceException if (compareResult > 0) { if (root.Left != null) { root.Left = Delete(root.Left, value, ref done); if (!done) { root = DeleteRebalanceLeft(root, ref done); } } else { throw new MeshNavException("Value not found"); } } else if (compareResult < 0) { if (root.Right != null) { root.Right = Delete(root.Right, value, ref done); if (!done) { root = DeleteRebalanceRight(root, ref done); } } else { throw new MeshNavException("Value not found"); } } // ReSharper restore PossibleNullReferenceException return(root); }