参考算法导论的伪代码写出,留个纪念,重点是要多画图理解
package tree;
public class RedBlackTree {
public static final int RED = 1;
public static final int BLACK = 2;
public static final RedBlackTree NIL = new RedBlackTree(Integer.MIN_VALUE, BLACK, null, null, null);
public int key;
public int color;
public RedBlackTree right;
public RedBlackTree left;
public RedBlackTree parent;
public RedBlackTree() {
super();
}
public RedBlackTree(int key, int color, RedBlackTree right, RedBlackTree left, RedBlackTree parent) {
super();
this.key = key;
this.color = color;
this.right = right;
this.left = left;
this.parent = parent;
}
public static void inOrderWalk(RedBlackTree x) {
if (x == null || x.equals(NIL)) {
return;
}
inOrderWalk(x.left);
System.out.println(x.key);
inOrderWalk(x.right);
}
private static RedBlackTree get(RedBlackTree x, int key) {
if (x == null || x.equals(NIL)) {
return null;
}
if (x.key == key) {
return x;
} else {
if (x.key > key) {
return get(x.left, key);
} else {
return get(x.right, key);
}
}
}
private static RedBlackTree rightRotate(RedBlackTree tree, int key) {
RedBlackTree target = get(tree, key);
if (target == null) {
return tree;
}
RedBlackTree targetParent = target.parent;
RedBlackTree targetLeftChild = target.left;
RedBlackTree targetLeftChildRightChild = target.left.right;
if (targetParent.equals(NIL)) {
tree = targetLeftChild;
} else if (targetParent.right == target) {
targetParent.right = target.left;
} else {
targetParent.left = target.left;
}
target.parent = targetLeftChild;
if (targetLeftChildRightChild != null) {
target.left = targetLeftChildRightChild;
if (targetLeftChildRightChild != NIL)
targetLeftChildRightChild.parent = target;
}
targetLeftChild.parent = targetParent;
targetLeftChild.right = target;
return tree;
}
private static RedBlackTree leftRotate(RedBlackTree tree, int key) {
RedBlackTree target = get(tree, key);
if (target == null) {
return tree;
}
RedBlackTree targetParent = target.parent;
RedBlackTree targetRightChild = target.right;
RedBlackTree targetRightChildLeftChild = target.right.left;
if (targetParent.equals(NIL)) {
tree = targetRightChild;
} else if (targetParent.left == target) {
targetParent.left = target.right;
} else {
targetParent.right = target.right;
}
target.parent = targetRightChild;
if (targetRightChildLeftChild != null) {
target.right = targetRightChildLeftChild;
if (targetRightChildLeftChild != NIL)
targetRightChildLeftChild.parent = target;
}
targetRightChild.parent = targetParent;
targetRightChild.left = target;
return tree;
}
public static RedBlackTree redBlackTreeInsert(RedBlackTree x, int key) {
RedBlackTree root = x;
RedBlackTree target = new RedBlackTree(key, RED, NIL, NIL, NIL);
while (true) {
if (x.key > key) {
if (!x.left.equals(NIL)) {
x = x.left;
} else {
x.left = target;
target.parent = x;
break;
}
} else {
if (x.key == key)
return root;
if (!x.right.equals(NIL)) {
x = x.right;
} else {
x.right = target;
target.parent = x;
break;
}
}
}
return keepBalanceOnInsert(root, target);
}
private static RedBlackTree keepBalanceOnInsert(RedBlackTree root, RedBlackTree target) {
while (target.parent.color == RED) {
if (target.parent == target.parent.parent.left) {
RedBlackTree uncle = target.parent.parent.right;
if (uncle.color == RED) {
target.parent.color = BLACK;
uncle.color = BLACK;
target.parent.parent.color = RED;
target = target.parent.parent;
} else {
if (target == target.parent.right) {
target = target.parent;
root = leftRotate(root, target.key);
}
target.parent.color = BLACK;
target.parent.parent.color = RED;
root = rightRotate(root, target.parent.parent.key);
}
} else {
RedBlackTree uncle = target.parent.parent.left;
if (uncle.color == RED) {
target.parent.color = BLACK;
uncle.color = BLACK;
target.parent.parent.color = RED;
target = target.parent.parent;
} else {
if (target == target.parent.left) {
target = target.parent;
root = rightRotate(root, target.key);
}
target.parent.color = BLACK;
target.parent.parent.color = RED;
root = leftRotate(root, target.parent.parent.key);
}
}
}
root.color = BLACK;
return root;
}
private static RedBlackTree transplant(RedBlackTree root, RedBlackTree deletion, RedBlackTree replace) {
if (deletion.parent == NIL) {
replace.parent = NIL;
return replace;
} else if (deletion == deletion.parent.left) {
deletion.parent.left = replace;
} else {
deletion.parent.right = replace;
}
replace.parent = deletion.parent;
return root;
}
private static RedBlackTree getMin(RedBlackTree root) {
while (root.left != NIL) {
root = root.left;
}
return root;
}
public static RedBlackTree redBlackTreeDelete(RedBlackTree root, int key) {
RedBlackTree target = get(root, key);
RedBlackTree x;
if (target == null) {
return root;
}
RedBlackTree mirror = target;
int originColor = target.color;
if (target.left == NIL) {
x = target.right;
root = transplant(root, target, target.right);
} else if (target.right == NIL) {
x = target.left;
root = transplant(root, target, target.left);
} else {
mirror = getMin(target.right);
originColor = mirror.color;
x = mirror.right;
if (mirror.parent == target) {
x.parent = mirror;
root = transplant(root, target, mirror);
mirror.color = target.color;
mirror.left = target.left;
mirror.left.parent = mirror;
} else {
if (x != NIL) {
root = transplant(root, mirror, x);
} else {
mirror.parent.left = x;
x.parent = mirror.parent;
}
target.key = mirror.key;
}
}
if (originColor == BLACK) {
root = fixup(root, x);
}
return root;
}
private static RedBlackTree fixup(RedBlackTree root, RedBlackTree x) {
while (x != root && x.color == BLACK) {
if (x == x.parent.left) {
RedBlackTree brother = x.parent.right;
if (brother.color == RED) {
brother.color = BLACK;
x.parent.color = RED;
root = leftRotate(root, x.parent.key);
brother = x.parent.right;
}
if (brother.left.color == BLACK && brother.right.color == BLACK) {
brother.color = RED;
x = x.parent;
} else {
if (brother.right.color == BLACK) {
brother.left.color = BLACK;
brother.color = RED;
root = rightRotate(root, brother.key);
brother = x.parent.right;
}
brother.color = x.parent.color;
x.parent.color = BLACK;
brother.right.color = BLACK;
root = leftRotate(root, x.parent.key);
x = root;
}
} else {
RedBlackTree brother = x.parent.left;
if (brother.color == RED) {
brother.color = BLACK;
x.parent.color = RED;
root = rightRotate(root, x.parent.key);
brother = x.parent.left;
}
if (brother.right.color == BLACK && brother.left.color == BLACK) {
brother.color = RED;
x = x.parent;
} else {
if (brother.left.color == BLACK) {
brother.right.color = BLACK;
brother.color = RED;
root = leftRotate(root, brother.key);
brother = x.parent.left;
}
brother.color = x.parent.color;
x.parent.color = BLACK;
brother.left.color = BLACK;
root = rightRotate(root, x.parent.key);
x = root;
}
}
}
x.color = BLACK;
return root;
}
}