private void DeleteCase1(IRbNode n) { if (n.Parent == null) return; DeleteCase2(n); }
//----------------------------------- private void InsertCase2(IRbNode n) { if (NodeColor(n.Parent) == Color.Black) return; // Tree is still valid InsertCase3(n); }
public void Delete(IRbNode template, out IRbNode deletedAlt) { deletedAlt = null; var n = LookupNode(template); if (n == null) { return; // Key not found, do nothing } if (n.Left != null && n.Right != null) { // Copy key/value from predecessor and then delete it instead var pred = MaximumNode(n.Left); pred.AssignValueTo(n); n = pred; deletedAlt = pred; } //assert n.left == null || n.right == null; var child = n.Right ?? n.Left; if (NodeColor(n) == Color.Black) { n.Color = NodeColor(child); DeleteCase1(n); } ReplaceNode(n, child); if (NodeColor(Root) == Color.Red) { Root.Color = Color.Black; } }
private static void PrintHelper(IRbNode n, int indent) { if (n == null) { Trace.WriteLine("<empty tree>"); return; } if (n.Left != null) { PrintHelper(n.Left, indent + _indentStep); } for (var i = 0; i < indent; i++) { Trace.Write(" "); } if (n.Color == Color.Black) { Trace.WriteLine(" " + n + " "); } else { Trace.WriteLine("<" + n + ">"); } if (n.Right != null) { PrintHelper(n.Right, indent + _indentStep); } }
//------------------------------------ private void InsertCase1(IRbNode n) { if (n.Parent == null) n.Color = Color.Black; else InsertCase2(n); }
internal void FireNodeOperation(IRbNode node, NodeOperation operation) { if (NodeOperation != null) { NodeOperation(node, operation); } }
private static IRbNode MaximumNode(IRbNode n) { //assert n != null; while (n.Right != null) { n = n.Right; } return(n); }
private static void VerifyProperty1(IRbNode n) { Assert.IsTrue(NodeColor(n) == Color.Red || NodeColor(n) == Color.Black); if (n == null) { return; } VerifyProperty1(n.Left); VerifyProperty1(n.Right); }
public bool TryLookup(IRbNode template, out IRbNode val) { var n = LookupNode(template); if (n == null) { val = null; return(false); } val = n; return(true); }
public void Insert(IRbNode newNode) { newNode.Color = Color.Red; var insertedNode = newNode; if (Root == null) { Root = insertedNode; } else { var n = Root; while (true) { var compResult = newNode.CompareTo(n); if (compResult == 0) { throw new RbTreeDuplicatedItemException( "RBNode " + newNode + " already present in tree"); } if (compResult < 0) { if (n.Left == null) { n.Left = insertedNode; break; } n = n.Left; } else { //assert compResult > 0; if (n.Right == null) { n.Right = insertedNode; break; } n = n.Right; } } insertedNode.Parent = n; } InsertCase1(insertedNode); NodeInserted?.Invoke(insertedNode); }
private void DeleteCase4(IRbNode n) { if (NodeColor(n.Parent) == Color.Red && NodeColor(n.Sibling()) == Color.Black && NodeColor(n.Sibling().Left) == Color.Black && NodeColor(n.Sibling().Right) == Color.Black) { n.Sibling().Color = Color.Red; n.Parent.Color = Color.Black; } else DeleteCase5(n); }
private void RotateLeft(IRbNode n) { var r = n.Right; ReplaceNode(n, r); n.Right = r.Left; if (r.Left != null) { r.Left.Parent = n; } r.Left = n; n.Parent = r; }
//---------------------------- private void InsertCase3(IRbNode n) { if (NodeColor(n.Uncle()) == Color.Red) { n.Parent.Color = Color.Black; n.Uncle().Color = Color.Black; n.Grandparent().Color = Color.Red; InsertCase1(n.Grandparent()); } else { InsertCase4(n); } }
private static void DoVisitTreeNodes(Action <IRbNode> action, IRbNode walker) { if (walker.Left != null) { DoVisitTreeNodes(action, walker.Left); } action?.Invoke(walker); if (walker.Right != null) { DoVisitTreeNodes(action, walker.Right); } }
//---------------------------- private void InsertCase5(IRbNode n) { n.Parent.Color = Color.Black; n.Grandparent().Color = Color.Red; if (Equals(n, n.Parent.Left) && Equals(n.Parent, n.Grandparent().Left)) { RotateRight(n.Grandparent()); } else { //assert n == n.parent.right && n.parent == n.grandparent().right; RotateLeft(n.Grandparent()); } }
private void DeleteCase3(IRbNode n) { if (NodeColor(n.Parent) == Color.Black && NodeColor(n.Sibling()) == Color.Black && NodeColor(n.Sibling().Left) == Color.Black && NodeColor(n.Sibling().Right) == Color.Black) { n.Sibling().Color = Color.Red; DeleteCase1(n.Parent); } else { DeleteCase4(n); } }
private void RotateRight(IRbNode n) { var l = n.Left; ReplaceNode(n, l); n.Left = l.Right; if (l.Right != null) { l.Right.Parent = n; } l.Right = n; n.Parent = l; }
//---------------------------- private void InsertCase4(IRbNode n) { if (Equals(n, n.Parent.Right) && Equals(n.Parent, n.Grandparent().Left)) { RotateLeft(n.Parent); n = n.Left; } else if (Equals(n, n.Parent.Left) && Equals(n.Parent, n.Grandparent().Right)) { RotateRight(n.Parent); n = n.Right; } InsertCase5(n); }
private void DeleteCase2(IRbNode n) { if (NodeColor(n.Sibling()) == Color.Red) { n.Parent.Color = Color.Red; n.Sibling().Color = Color.Black; if (Equals(n, n.Parent.Left)) RotateLeft(n.Parent); else RotateRight(n.Parent); } DeleteCase3(n); }
private static void VerifyProperty4(IRbNode n) { if (NodeColor(n) == Color.Red) { Assert.IsTrue((NodeColor(n.Left) == Color.Black)); Assert.IsTrue((NodeColor(n.Right) == Color.Black)); Assert.IsTrue((NodeColor(n.Parent) == Color.Black)); } if (n == null) { return; } VerifyProperty4(n.Left); VerifyProperty4(n.Right); }
private IRbNode LookupNode(IRbNode template) { var n = Root; while (n != null) { var compResult = template.CompareTo(n); if (compResult == 0) { return(n); } n = compResult < 0 ? n.Left : n.Right; } return(null); }
private void DeleteCase6(IRbNode n) { n.Sibling().Color = NodeColor(n.Parent); n.Parent.Color = Color.Black; if (Equals(n, n.Parent.Left)) { //assert nodeColor(n.sibling().right) == Color.RED; n.Sibling().Right.Color = Color.Black; RotateLeft(n.Parent); } else { //assert nodeColor(n.sibling().left) == Color.RED; n.Sibling().Left.Color = Color.Black; RotateRight(n.Parent); } }
private void ReplaceNode(IRbNode oldn, IRbNode newn) { if (oldn.Parent == null) { Root = newn; } else { if (Equals(oldn, oldn.Parent.Left)) oldn.Parent.Left = newn; else oldn.Parent.Right = newn; } if (newn != null) { newn.Parent = oldn.Parent; } }
private void DeleteCase5(IRbNode n) { if (Equals(n, n.Parent.Left) && NodeColor(n.Sibling()) == Color.Black && NodeColor(n.Sibling().Left) == Color.Red && NodeColor(n.Sibling().Right) == Color.Black) { n.Sibling().Color = Color.Red; n.Sibling().Left.Color = Color.Black; RotateRight(n.Sibling()); } else if (Equals(n, n.Parent.Right) && NodeColor(n.Sibling()) == Color.Black && NodeColor(n.Sibling().Right) == Color.Red && NodeColor(n.Sibling().Left) == Color.Black) { n.Sibling().Color = Color.Red; n.Sibling().Right.Color = Color.Black; RotateLeft(n.Sibling()); } DeleteCase6(n); }
private static int VerifyProperty5Helper(IRbNode n, int blackCount, int pathBlackCount) { if (NodeColor(n) == Color.Black) { blackCount++; } if (n == null) { if (pathBlackCount == -1) { pathBlackCount = blackCount; } else { Assert.IsTrue(blackCount == pathBlackCount); } return(pathBlackCount); } pathBlackCount = VerifyProperty5Helper(n.Left, blackCount, pathBlackCount); pathBlackCount = VerifyProperty5Helper(n.Right, blackCount, pathBlackCount); return(pathBlackCount); }
private static void VerifyProperty5(IRbNode root) { VerifyProperty5Helper(root, 0, -1); }
private static Color NodeColor(IRbNode n) { return(n == null ? Color.Black : n.Color); }
private static void VerifyProperty2(IRbNode root) { Assert.IsTrue(NodeColor(root) == Color.Black); }
public RbTree(IRbNode root) { Root = root; }