private void Rotate(TNode node, RBTreeDirection direction) { RBTreeDirection oppositeDirection = OppositeDirection(direction); //replacement will rotate to where node was, pushing node down TNode replacement = node.GetChild(oppositeDirection); node.SetChild(replacement.GetChild(direction), oppositeDirection); if (replacement.GetChild(direction) != SentinelNode) { replacement.GetChild(direction).parent = node; } if (replacement != SentinelNode) { replacement.parent = node.parent; } if (node.HasParent) { node.parent.SetChild(replacement, node.ChildDirection); } else { Root = replacement; } replacement.SetChild(node, direction); if (node != SentinelNode) { node.parent = replacement; } }
/// <summary> /// Enumerate the nodes in the tree. /// </summary> public IEnumerable <TNode> GetNodes(bool ascending) { RBTreeDirection direction = (ascending ? RBTreeDirection.Right : RBTreeDirection.Left); for (TNode node = SentinelNode.GetNeighbor(direction); node != SentinelNode; node = node.GetNeighbor(direction)) { yield return(node); } }
internal void SetChild(TNode child, RBTreeDirection direction) { if (direction == RBTreeDirection.Left) { left = child; } else { right = child; } }
private void RestorePropertiesAfterRemove(TNode node) { while (node != Root && node.color == RBTreeNodeColor.Black) { RBTreeDirection direction = node.ChildDirection; RBTreeDirection oppositeDirection = OppositeDirection(direction); TNode sibling = node.Sibling; if (sibling.color == RBTreeNodeColor.Red) { sibling.color = RBTreeNodeColor.Black; node.parent.color = RBTreeNodeColor.Red; Rotate(node.parent, direction); sibling = node.parent.GetChild(oppositeDirection); } if ((sibling.left.color == RBTreeNodeColor.Black) && (sibling.right.color == RBTreeNodeColor.Black)) { sibling.color = RBTreeNodeColor.Red; node = node.parent; } else { if (sibling.GetChild(oppositeDirection).color == RBTreeNodeColor.Black) { sibling.GetChild(direction).color = RBTreeNodeColor.Black; sibling.color = RBTreeNodeColor.Red; Rotate(sibling, oppositeDirection); sibling = node.parent.GetChild(oppositeDirection); } sibling.color = node.parent.color; node.parent.color = RBTreeNodeColor.Black; sibling.GetChild(oppositeDirection).color = RBTreeNodeColor.Black; Rotate(node.parent, direction); node = Root; } } node.color = RBTreeNodeColor.Black; }
private TNode FindExtremum(Predicate <TKey> predicate, RBTreeDirection direction) { RBTreeDirection oppositeDirection = OppositeDirection(direction); TNode extremum = null; TNode node = Root; while (node != SentinelNode) { if (predicate(node.Key)) { extremum = node; node = node.GetChild(direction); } else { node = node.GetChild(oppositeDirection); } } return(extremum); }
private TNode TraverseToFindNeighbor(TNode node, RBTreeDirection direction) { if (node.GetChild(direction) == SentinelNode) { while (node.HasParent && node.ChildDirection == direction) { node = node.parent; } return(node.HasParent ? node.parent : SentinelNode); } else { node = node.GetChild(direction); RBTreeDirection oppositeDirection = OppositeDirection(direction); while (node.GetChild(oppositeDirection) != SentinelNode) { node = node.GetChild(oppositeDirection); } return(node); } }
private void RestorePropertiesAfterAdd(TNode node) { while (node != Root && node.parent.color == RBTreeNodeColor.Red) { TNode uncle = node.parent.Sibling; if (uncle != null && uncle.color == RBTreeNodeColor.Red) { TNode parent = node.parent; TNode grandparent = parent.parent; grandparent.color = RBTreeNodeColor.Red; parent.color = RBTreeNodeColor.Black; uncle.color = RBTreeNodeColor.Black; node = grandparent; } else { RBTreeDirection grandparentToParent = node.parent.ChildDirection; RBTreeDirection parentToNode = node.ChildDirection; if (grandparentToParent != parentToNode) { node = node.parent; Rotate(node, grandparentToParent); } TNode parent = node.parent; TNode grandparent = parent.parent; grandparent.color = RBTreeNodeColor.Red; parent.color = RBTreeNodeColor.Black; Rotate(grandparent, OppositeDirection(grandparentToParent)); } } Root.color = RBTreeNodeColor.Black; }
private TNode FindRangeExtremum(KeyRangePredicate rangePredicate, RBTreeDirection direction) { TNode extremum = null; TNode node = Root; while (node != SentinelNode) { int result = rangePredicate(node.Key); if (result == 0) { extremum = node; node = node.GetChild(direction); } else if (result < 0) { node = node.right; } else { node = node.left; } } return(extremum); }
internal TNode GetChild(RBTreeDirection direction) { return(direction == RBTreeDirection.Left ? left : right); }
internal TNode GetNeighbor(RBTreeDirection direction) { return(direction == RBTreeDirection.Left ? predecessor : successor); }
private static RBTreeDirection OppositeDirection(RBTreeDirection dir) { return(dir == RBTreeDirection.Left ? RBTreeDirection.Right : RBTreeDirection.Left); }