public void Add(T node) { if (Root == null) { Count = 1; Root = node; FixTreeOnInsert(node); return; } IRedBlackTreeNode parent = Root; while (true) { if (((IComparable)parent).CompareTo(node) <= 0) { if (parent.Left == null) { InsertLeft(parent, node); break; } parent = parent.Left; } else { if (parent.Right == null) { InsertRight(parent, node); break; } parent = parent.Right; } } }
void InternalRemove (IRedBlackTreeNode node) { if (node.Left != null && node.Right != null) { IRedBlackTreeNode outerLeft = node.Right.GetOuterLeft (); InternalRemove (outerLeft); Replace (node, outerLeft); outerLeft.Color = node.Color; outerLeft.Left = node.Left; if (outerLeft.Left != null) outerLeft.Left.Parent = outerLeft; outerLeft.Right = node.Right; if (outerLeft.Right != null) outerLeft.Right.Parent = outerLeft; outerLeft.UpdateAugmentedData (); return; } Count--; // node has only one child IRedBlackTreeNode child = node.Left ?? node.Right; Replace (node, child); if (node.Color == RedBlackColor.Black && child != null) { if (child.Color == RedBlackColor.Red) { child.Color = RedBlackColor.Black; } else { DeleteOneChild (child); } } }
public static T GetUncle<T> (this T node) where T : class, IRedBlackTreeNode { IRedBlackTreeNode grandparent = node.GetGrandparent (); if (grandparent == null) return null; return (T)(node.Parent == grandparent.Left ? grandparent.Right : grandparent.Left); }
public static T GetOuterLeft<T> (this T node) where T : class, IRedBlackTreeNode { IRedBlackTreeNode result = node; while (result.Left != null) result = result.Left; return (T)result; }
public void Remove(IRedBlackTreeNode node) { if (node.Left != null && node.Right != null) { IRedBlackTreeNode outerLeft = node.Right.GetOuterLeft(); InternalRemove(outerLeft); Replace(node, outerLeft); outerLeft.Color = node.Color; outerLeft.Left = node.Left; if (outerLeft.Left != null) { outerLeft.Left.Parent = outerLeft; } outerLeft.Right = node.Right; if (outerLeft.Right != null) { outerLeft.Right.Parent = outerLeft; } outerLeft.UpdateAugmentedData(); OnNodeRemoved(new RedBlackTreeNodeEventArgs((T)node)); return; } InternalRemove(node); OnNodeRemoved(new RedBlackTreeNodeEventArgs((T)node)); }
static void AppendNode(StringBuilder builder, IRedBlackTreeNode node, int indent) { builder.Append(GetIndent(indent) + "Node (" + (node.Color == RedBlackColor.Red ? "r" : "b") + "):" + node + Environment.NewLine); builder.Append(GetIndent(indent) + "Left: "); if (node.Left != null) { builder.Append(Environment.NewLine); AppendNode(builder, node.Left, indent + 1); } else { builder.Append("null"); } builder.Append(Environment.NewLine); builder.Append(GetIndent(indent) + "Right: "); if (node.Right != null) { builder.Append(Environment.NewLine); AppendNode(builder, node.Right, indent + 1); } else { builder.Append("null"); } }
public void InsertBefore (IRedBlackTreeNode node, IRedBlackTreeNode newNode) { if (node.Left == null) { InsertLeft (node, newNode); } else { InsertRight (node.Left.GetOuterRight (), newNode); } }
public static T GetOuterRight<T> (this T node) where T : class, IRedBlackTreeNode { IRedBlackTreeNode result = node; while (result.Right != null) { result = result.Right; } return (T)result; }
public void InsertRight(IRedBlackTreeNode parentNode, IRedBlackTreeNode newNode) { parentNode.Right = newNode; newNode.Parent = parentNode; newNode.Color = RedBlackColor.Red; parentNode.UpdateAugmentedData(); FixTreeOnInsert(newNode); Count++; }
public void InsertAfter(IRedBlackTreeNode node, IRedBlackTreeNode newNode) { if (node.Right == null) { InsertRight(node, newNode); } else { InsertLeft(node.Right.GetOuterLeft(), newNode); } }
void RotateRight (IRedBlackTreeNode node) { IRedBlackTreeNode left = node.Left; Replace (node, left); node.Left = left.Right; if (node.Left != null) node.Left.Parent = node; left.Right = node; node.Parent = left; node.UpdateAugmentedData (); node.Parent.UpdateAugmentedData (); }
void RotateLeft (IRedBlackTreeNode node) { IRedBlackTreeNode right = node.Right; Replace (node, right); node.Right = right.Left; if (node.Right != null) node.Right.Parent = node; right.Left = node; node.Parent = right; node.UpdateAugmentedData (); node.Parent.UpdateAugmentedData (); }
public static T GetNextNode<T> (this T node) where T : class, IRedBlackTreeNode { if (node.Right == null) { IRedBlackTreeNode curNode = node; IRedBlackTreeNode oldNode; do { oldNode = curNode; curNode = curNode.Parent; } while (curNode != null && curNode.Right == oldNode); return (T)curNode; } return (T)node.Right.GetOuterLeft (); }
void FixTreeOnInsert(IRedBlackTreeNode node) { var parent = node.Parent; if (parent == null) { node.Color = RedBlackColor.Black; return; } if (parent.Color == RedBlackColor.Black) { return; } var uncle = node.GetUncle(); IRedBlackTreeNode grandParent = parent.Parent; if (uncle != null && uncle.Color == RedBlackColor.Red) { parent.Color = RedBlackColor.Black; uncle.Color = RedBlackColor.Black; grandParent.Color = RedBlackColor.Red; FixTreeOnInsert(grandParent); return; } if (node == parent.Right && parent == grandParent.Left) { RotateLeft(parent); node = node.Left; } else if (node == parent.Left && parent == grandParent.Right) { RotateRight(parent); node = node.Right; } parent = node.Parent; grandParent = parent.Parent; parent.Color = RedBlackColor.Black; grandParent.Color = RedBlackColor.Red; if (node == parent.Left && parent == grandParent.Left) { RotateRight(grandParent); } else { RotateLeft(grandParent); } }
void Replace (IRedBlackTreeNode oldNode, IRedBlackTreeNode newNode) { if (newNode != null) newNode.Parent = oldNode.Parent; if (oldNode.Parent == null) { Root = (T)newNode; } else { if (oldNode.Parent.Left == oldNode) oldNode.Parent.Left = newNode; else oldNode.Parent.Right = newNode; oldNode.Parent.UpdateAugmentedData (); } }
public static T GetPrevNode <T>(this T node) where T : class, IRedBlackTreeNode <T> { if (node.Left == null) { IRedBlackTreeNode <T> curNode = node; IRedBlackTreeNode <T> oldNode; do { oldNode = curNode; curNode = curNode.Parent; } while (curNode != null && curNode.Left == oldNode); return((T)curNode); } return((T)node.Left.GetOuterRight()); }
private void AssertNode <T>(T expectedValue, bool expectedIsRed, bool expectedIsLeaf, IRedBlackTreeNode <T> actualNode) { Assert.Equal(expectedValue, actualNode.Value); if (expectedIsRed) { Assert.False(actualNode.IsBlack); Assert.True(actualNode.IsRed); } else { Assert.True(actualNode.IsBlack); Assert.False(actualNode.IsRed); } if (expectedIsLeaf) { Assert.True(actualNode.IsLeaf); } else { Assert.False(actualNode.IsLeaf); } }
void DeleteOneChild(IRedBlackTreeNode node) { // case 1 if (node == null || node.Parent == null) { return; } var parent = node.Parent; var sibling = node.GetSibling(); if (sibling == null) { return; } // case 2 if (sibling.Color == RedBlackColor.Red) { parent.Color = RedBlackColor.Red; sibling.Color = RedBlackColor.Black; if (node == parent.Left) { RotateLeft(parent); } else { RotateRight(parent); } sibling = node.GetSibling(); if (sibling == null) { return; } } // case 3 if (parent.Color == RedBlackColor.Black && sibling.Color == RedBlackColor.Black && GetColorSafe(sibling.Left) == RedBlackColor.Black && GetColorSafe(sibling.Right) == RedBlackColor.Black) { sibling.Color = RedBlackColor.Red; DeleteOneChild(parent); return; } // case 4 if (parent.Color == RedBlackColor.Red && sibling.Color == RedBlackColor.Black && GetColorSafe(sibling.Left) == RedBlackColor.Black && GetColorSafe(sibling.Right) == RedBlackColor.Black) { sibling.Color = RedBlackColor.Red; parent.Color = RedBlackColor.Black; return; } // case 5 if (node == parent.Left && sibling.Color == RedBlackColor.Black && GetColorSafe(sibling.Left) == RedBlackColor.Red && GetColorSafe(sibling.Right) == RedBlackColor.Black) { sibling.Color = RedBlackColor.Red; if (sibling.Left != null) { sibling.Left.Color = RedBlackColor.Black; } RotateRight(sibling); } else if (node == parent.Right && sibling.Color == RedBlackColor.Black && GetColorSafe(sibling.Right) == RedBlackColor.Red && GetColorSafe(sibling.Left) == RedBlackColor.Black) { sibling.Color = RedBlackColor.Red; if (sibling.Right != null) { sibling.Right.Color = RedBlackColor.Black; } RotateLeft(sibling); } // case 6 sibling = node.GetSibling(); if (sibling == null) { return; } sibling.Color = parent.Color; parent.Color = RedBlackColor.Black; if (node == parent.Left) { if (sibling.Right != null) { sibling.Right.Color = RedBlackColor.Black; } RotateLeft(parent); } else { if (sibling.Left != null) { sibling.Left.Color = RedBlackColor.Black; } RotateRight(parent); } }
public static bool IsLeaf(this IRedBlackTreeNode node) { return(node.Left == null && node.Right == null); }
static RedBlackColor GetColorSafe(IRedBlackTreeNode node) { return(node != null ? node.Color : RedBlackColor.Black); }