private void RestoreAfterInsert(OrderedTreeNode x)
{
// x and y are used as variable names for brevity, in a more formal
// implementation, you should probably change the names
OrderedTreeNode y;
// maintain red-black tree properties after adding x
while(x != rbTree && x.Parent.Color == OrderedTreeNode.RED) {
// Parent node is .Colored red;
if(x.Parent == x.Parent.Parent.Left) { // determine traversal path
// is it on the Left or Right subtree?
y = x.Parent.Parent.Right; // get uncle
if(y!= null && y.Color == OrderedTreeNode.RED) {
// uncle is red; change x's Parent and uncle to black
x.Parent.Color = OrderedTreeNode.BLACK;
y.Color = OrderedTreeNode.BLACK;
// grandparent must be red. Why? Every red node that is not
// a leaf has only black children
x.Parent.Parent.Color = OrderedTreeNode.RED;
x = x.Parent.Parent; // continue loop with grandparent
}
else {
// uncle is black; determine if x is greater than Parent
if(x == x.Parent.Right) {
// yes, x is greater than Parent; rotate Left
// make x a Left child
x = x.Parent;
RotateLeft(x);
}
// no, x is less than Parent
x.Parent.Color = OrderedTreeNode.BLACK; // make Parent black
x.Parent.Parent.Color = OrderedTreeNode.RED; // make grandparent black
RotateRight(x.Parent.Parent); // rotate right
}
}
else {
// x's Parent is on the Right subtree
// this code is the same as above with "Left" and "Right" swapped
y = x.Parent.Parent.Left;
if(y!= null && y.Color == OrderedTreeNode.RED) {
x.Parent.Color = OrderedTreeNode.BLACK;
y.Color = OrderedTreeNode.BLACK;
x.Parent.Parent.Color = OrderedTreeNode.RED;
x = x.Parent.Parent;
}
else {
if(x == x.Parent.Left) {
x = x.Parent;
RotateRight(x);
}
x.Parent.Color = OrderedTreeNode.BLACK;
x.Parent.Parent.Color = OrderedTreeNode.RED;
RotateLeft(x.Parent.Parent);
}
}
}
rbTree.Color = OrderedTreeNode.BLACK; // rbTree should always be black
}