<pre name="code" class="java">/*
* 紅黑樹
*/
public class RedBlackTree {
public static final RbTreeNode NIL = new RbTreeNode(RbColor.BLACK);
private RbTreeNode root = null;
public static void main(String[] args) {
RedBlackTree rbt = new RedBlackTree();
//測試插入 page 179 紅黑樹不唯一
rbt.insertRbTreeNode(new RbTreeNode(11,RbColor.BLACK));
rbt.insertRbTreeNode(new RbTreeNode(2,RbColor.RED));
rbt.insertRbTreeNode(new RbTreeNode(1,RbColor.BLACK));
rbt.insertRbTreeNode(new RbTreeNode(7,RbColor.BLACK));
rbt.insertRbTreeNode(new RbTreeNode(5,RbColor.RED));
rbt.insertRbTreeNode(new RbTreeNode(8,RbColor.RED));
rbt.insertRbTreeNode(new RbTreeNode(14,RbColor.BLACK));
rbt.insertRbTreeNode(new RbTreeNode(15,RbColor.RED));
rbt.printTree();
rbt.deleteRbTreeNode(rbt.searchRbTreeNode(rbt.root, 7));
rbt.printTree();
System.out.println("最大節點的鍵爲:"+rbt.searchMaximum(rbt.root).key);
}
public RedBlackTree() {
this.root = NIL;
}
//中序遍歷二叉樹
private void traverseTree(RbTreeNode x) {
if(x != NIL) {
traverseTree(x.left);
System.out.print(x.key + " " + x.color + " ");
traverseTree(x.right);
}
}
private void printTree() {
System.out.println("root:"+root.key+" "+root.color);
traverseTree(root);
System.out.println();
}
//查找某一子節點
private RbTreeNode searchRbTreeNode(RbTreeNode x,int key) {
while(x != NIL && key != x.key) {
if(key < x.key) {
x = x.left;
} else {
x = x.right;
}
}
return x;
}
//插入某一子節點
private void insertRbTreeNode(RbTreeNode z) {
RbTreeNode y = NIL;
RbTreeNode x = root;
while(x != NIL) {
y = x;
if(z.key < x.key) {
x = x.left;
} else {
x = x.right;
}
}
z.parent = y;
if(y == NIL) {
root = z;
} else if(z.key < y.key) {
y.left = z;
} else {
y.right = z;
}
z.left = NIL;
z.right = NIL;
z.color = RbColor.RED;
rbInsertFixUp(z); //插入修正
}
//插入修正
private void rbInsertFixUp(RbTreeNode z) {
RbTreeNode y = null;
while(z.parent.color == RbColor.RED) { //當z的父節點是黑色時,不需要矯正
if(z.parent == z.parent.parent.left) { //左分支情況
y = z.parent.parent.right; //根據叔節點分情況
if(y.color == RbColor.RED) {
z.parent.color = RbColor.BLACK;
y.color = RbColor.BLACK;
z.parent.parent.color = RbColor.RED;
z = z.parent.parent;
} else {
if(z == z.parent.right) {
z = z.parent;
leftRotate(z);
}
z.parent.color = RbColor.BLACK;
z.parent.parent.color = RbColor.RED;
rightRotate(z.parent.parent);
}
} else {
y = z.parent.parent.left; //根據叔節點分情況
if(y.color == RbColor.RED) {
z.parent.color = RbColor.BLACK;
y.color = RbColor.BLACK;
z.parent.parent.color = RbColor.RED;
z = z.parent.parent;
} else {
if(z == z.parent.left) {
z = z.parent;
rightRotate(z);
}
z.parent.color = RbColor.BLACK;
z.parent.parent.color = RbColor.RED;
leftRotate(z.parent.parent);
}
}
}
root.color = RbColor.BLACK;
}
//刪除某一子節點
private void deleteRbTreeNode(RbTreeNode z) {
RbTreeNode y = z;
RbTreeNode x = NIL;
RbColor yOriginalColor = y.color;
if(z.left == NIL) {
x = z.right;
rbTransplant(z,z.right);
} else if(z.right == NIL) {
x = z.left;
rbTransplant(z,z.left);
} else {
y = searchMinimum(z.right);
yOriginalColor = y.color;
x = y.right;
if(y.parent == z) {
x.parent = y;
} else {
rbTransplant(y,y.right);
y.right = z.right;
z.right.parent = y;
}
rbTransplant(z,y);
y.left = z.left;
z.left.parent = y;
y.color = z.color;
}
if(yOriginalColor == RbColor.BLACK) {
rbDeleteFixUp(x);
}
}
private void rbDeleteFixUp(RbTreeNode x) {
//x總是指向一個具有雙重黑色的非根節點
RbTreeNode w = NIL;
while(x != root && x.color == RbColor.BLACK) {
if(x == x.parent.left) {
w = x.parent.right; //w指向兄節點
if(w.color == RbColor.RED) {
w.color = RbColor.BLACK; //case 1
x.parent.color = RbColor.RED; //case 1
leftRotate(x.parent); //case 1
w = x.parent.right; //case 1
}
if(w.left.color == RbColor.BLACK
&& w.right.color == RbColor.BLACK) {
w.color = RbColor.BLACK; //case 2
x = x.parent; //case 2
}
else {
if(w.right.color == RbColor.BLACK) {
w.left.color = RbColor.BLACK; //case 3
w.color = RbColor.RED; //case 3
rightRotate(w); //case 3
w = x.parent.right; //case 3
}
w.color = x.parent.color; //case 4
x.parent.color = RbColor.BLACK; //case 4
w.right.color = RbColor.BLACK; //case 4
leftRotate(x.parent); //case 4
x = root; //case 4
}
} else {
w = x.parent.left; //w指向兄節點
if(w.color == RbColor.RED) {
w.color = RbColor.BLACK; //case 1
x.parent.color = RbColor.RED; //case 1
rightRotate(x.parent); //case 1
w = x.parent.left; //case 1
}
if(w.right.color == RbColor.BLACK
&& w.left.color == RbColor.BLACK) {
w.color = RbColor.BLACK; //case 2
x = x.parent; //case 2
}
else {
if(w.left.color == RbColor.BLACK) {
w.right.color = RbColor.BLACK; //case 3
w.color = RbColor.RED; //case 3
leftRotate(w); //case 3
w = x.parent.left; //case 3
}
w.color = x.parent.color;
x.parent.color = RbColor.BLACK;
w.left.color = RbColor.BLACK;
rightRotate(x.parent);
x = root;
}
}
}
}
private void rbTransplant(RbTreeNode u,RbTreeNode v) {
if(u.parent == NIL) {
root = v;
} else if(u == u.parent.left) {
u.parent.left = v;
} else {
u.parent.right = v;
}
v.parent = u.parent;
}
//獲取最小鍵值節點
private RbTreeNode searchMinimum(RbTreeNode x) {
while(x.left != NIL) {
x = x.left;
}
return x;
}
//獲取最大鍵值節點
private RbTreeNode searchMaximum(RbTreeNode x) {
while(x.right != NIL) {
x = x.right;
}
return x;
}
//左旋
private void leftRotate(RbTreeNode x) {
RbTreeNode y = x.right;
x.right = y.left;
if(x.right != NIL) {
y.left.parent = x;
}
y.parent = x.parent;
if(x.parent == NIL) { //如果是根節點
root = y;
} else if(x == x.parent.left) {
x.parent.left = y;
} else {
x.parent.right = y;
}
y.left = x;
x.parent = y;
}
//右旋
private void rightRotate(RbTreeNode y) {
RbTreeNode x = y.left;
y.left = x.right;
if(x.right != NIL) {
x.right.parent = y;
}
x.parent = y.parent;
if(y.parent == NIL) {
root = x;
} else if(y == y.parent.left) {
y.parent.left = x;
} else {
y.parent.right = x;
}
x.right = y;
y.parent = x;
}
//紅黑樹節點類
private static class RbTreeNode {
RbTreeNode left = null;
RbTreeNode right = null;
RbTreeNode parent = null;
RbColor color = RbColor.RED;
int key = 0;
public RbTreeNode(int key,RbColor color) {
this.key = key;
this.color = color;
}
public RbTreeNode(RbColor color) {
this.color = color;
}
}
private enum RbColor {
RED,BLACK
}
}
運行結果爲:
root:7 BLACK
1 BLACK 2 RED 5 BLACK 7 BLACK 8 BLACK 11 RED 14 BLACK 15 RED
root:7 BLACK
2 RED 5 BLACK 7 BLACK 8 BLACK 11 RED 14 BLACK 15 RED
最大節點的鍵爲:15