《算法导论》红黑树详解(一):概念
《算法导论》红黑树详解(二):Java实现Demo
使用Java简单地实现红黑树,代码如下:
/** * 红黑树实现demo */
public class RedBlackTree<Key extends Comparable<Key>> {
private static final boolean RED = false;
private static final boolean BLACK = true;
/** * 叶结点 */
private final Node nil = new Node();
/** * 根结点初始化为nil */
private Node root = nil;
/** * 结点类 */
private class Node {
private Key key;
private Node left;
private Node right;
private Node parent;
private boolean color = BLACK;
public Node() {
}
public Node(Key key) {
this.key = key;
}
@Override
public String toString() {
String nodeColor = color ? "BLACK" : "RED";
return " " + key + "-" + nodeColor + " ";
}
}
/** * 左旋 * @param x */
private void leftRotate(Node x){
Node y = x.right;
x.right = y.left;
if (y.left != 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;
}
/** * 右旋 * @param x */
private void rightRotate(Node x) {
Node y = x.left;
x.left = y.right;
if (y.right != nil) {
y.right.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.right = x;
x.parent = y;
}
/** * 插入 * @param key */
public void insert(Key key) {
if (key == null) {
return;
}
Node y = nil;
Node x = root;
while (x != nil) {
y = x;
if (key.compareTo(x.key) < 0) {
x = x.left;
} else if (key.compareTo(x.key) > 0) {
x = x.right;
} else { //重复结点不插入
return;
}
}
Node z = new Node(key);
z.parent = y;
if (y == nil) {
root = z;
} else if (z.key.compareTo(y.key) < 0) {
y.left = z;
} else {
y.right = z;
}
z.left = nil;
z.right = nil;
z.color = RED;
insertFixup(z);
}
/** * 插入修复 * @param z */
private void insertFixup(Node z) {
while (z.parent.color == RED) {
if (z.parent == z.parent.parent.left) {
Node y = z.parent.parent.right;
if (y.color == RED) {
z.parent.color = BLACK;
y.color = BLACK;
z.parent.parent.color = RED;
z = z.parent.parent;
} else {
if (z == z.parent.right) {
z = z.parent;
leftRotate(z);
}
z.parent.color = BLACK;
z.parent.parent.color = RED;
rightRotate(z.parent.parent);
}
} else {
Node y = z.parent.parent.left;
if (y.color == RED) {
z.parent.color = BLACK;
y.color = BLACK;
z.parent.parent.color = RED;
z = z.parent.parent;
} else {
if (z == z.parent.left) {
z = z.parent;
rightRotate(z);
}
z.parent.color = BLACK;
z.parent.parent.color = RED;
leftRotate(z.parent.parent);
}
}
}
root.color = BLACK;
}
/** * 用v子树替换u子树 * @param u * @param v */
private void transplant(Node u, Node 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;
}
/** * 查找以x为根的最小结点 * @param x * @return */
private Node minimum(Node x) {
while (x.left != nil) {
x = x.left;
}
return x;
}
/** * 查找结点的key值为key的结点 * @param key * @return */
private Node search(Key key) {
Node x = root;
while (x != nil && key.compareTo(x.key) != 0) {
if (key.compareTo(x.key) < 0) {
x = x.left;
} else {
x = x.right;
}
}
return x;
}
/** * 删除结点的key值为key的结点 * @param key */
public void delete(Key key) {
if (key == null) {
return;
}
Node z = search(key);
if (z == nil) {
return;
}
Node y = z;
Node x;
boolean yOriginalColor = y.color;
if (z.left == nil) {
x = z.right;
transplant(z, z.right);
} else if (z.right == nil) {
x = z.left;
transplant(z, z.left);
} else {
y = minimum(z.right);
yOriginalColor = y.color;
x = y.right;
if (y.parent == z) {
x.parent = y;
} else {
transplant(y, y.right);
y.right = z.right;
y.right.parent = y;
}
transplant(z, y);
y.left = z.left;
y.left.parent = y;
y.color = z.color;
}
if (yOriginalColor == BLACK) {
deleteFixup(x);
}
}
/** * 删除修复 * @param x */
private void deleteFixup(Node x) {
while (x != root && x.color == BLACK) {
if (x == x.parent.left) {
Node w = x.parent.right;
if (w.color == RED) {
w.color = BLACK;
x.parent.color = RED;
leftRotate(x.parent);
w = x.parent.right;
}
if (w.left.color == BLACK && w.right.color == BLACK) {
w.color = RED;
x = x.parent;
} else {
if (w.right.color == BLACK) {
w.left.color = BLACK;
w.color = RED;
rightRotate(w);
w = x.parent.right;
}
w.color = x.parent.color;
x.parent.color = BLACK;
w.right.color = BLACK;
leftRotate(x.parent);
x = root;
}
} else {
Node w = x.parent.left;
if (w.color == RED) {
w.color = BLACK;
x.parent.color = RED;
leftRotate(x.parent);
w = x.parent.left;
}
if (w.left.color == BLACK && w.right.color == BLACK) {
w.color = RED;
x = x.parent;
} else {
if (w.left.color == BLACK) {
w.right.color = BLACK;
w.color = RED;
leftRotate(w);
w = x.parent.left;
}
w.color = x.parent.color;
x.parent.color = BLACK;
w.left.color = BLACK;
rightRotate(x.parent);
x = root;
}
}
}
x.color = BLACK;
}
/** * 先序遍历 */
public void preOrder() {
preOrder(root);
}
/** * 对以x为根的子树进行先序遍历 * @param x */
private void preOrder(Node x) {
if (x != nil) {
System.out.print(x);
preOrder(x.left);
preOrder(x.right);
}
}
/** * 中序遍历 */
public void inOrder() {
inOrder(root);
}
/** * 对以x为根的子树进行中序遍历 * @param x */
private void inOrder(Node x) {
if (x != nil) {
inOrder(x.left);
System.out.print(x);
inOrder(x.right);
}
}
/** * 后序遍历 */
public void postOrder() {
postOrder(root);
}
/** * 对以x为根的子树进行后序遍历 * @param x */
private void postOrder(Node x) {
if (x != nil) {
postOrder(x.left);
postOrder(x.right);
System.out.print(x);
}
}
public static void main(String[] args) {
RedBlackTree<Integer> redBlackTree = new RedBlackTree<>();
//构造一颗红黑树 可参考上一篇中完整的插入修复图例
redBlackTree.insert(11);
redBlackTree.insert(2);
redBlackTree.insert(14);
redBlackTree.insert(15);
redBlackTree.insert(1);
redBlackTree.insert(7);
redBlackTree.insert(5);
redBlackTree.insert(8);
System.out.println("原红黑树:");
System.out.print("先序遍历:");
redBlackTree.preOrder();
System.out.print("\n中序遍历:");
redBlackTree.inOrder();
System.out.print("\n后序遍历:");
redBlackTree.postOrder();
System.out.println();
//插入元素4
redBlackTree.insert(4);
System.out.println("插入元素4后:");
System.out.print("先序遍历:");
redBlackTree.preOrder();
System.out.print("\n中序遍历:");
redBlackTree.inOrder();
System.out.print("\n后序遍历:");
redBlackTree.postOrder();
System.out.println();
//删除元素5
redBlackTree.delete(5);
System.out.println("删除元素5后:");
System.out.print("先序遍历:");
redBlackTree.preOrder();
System.out.print("\n中序遍历:");
redBlackTree.inOrder();
System.out.print("\n后序遍历:");
redBlackTree.postOrder();
System.out.println();
}
}
运行结果:
原红黑树:
先序遍历: 11-BLACK 2-RED 1-BLACK 7-BLACK 5-RED 8-RED 14-BLACK 15-RED
中序遍历: 1-BLACK 2-RED 5-RED 7-BLACK 8-RED 11-BLACK 14-BLACK 15-RED
后序遍历: 1-BLACK 5-RED 8-RED 7-BLACK 2-RED 15-RED 14-BLACK 11-BLACK
插入元素4后:
先序遍历: 7-BLACK 2-RED 1-BLACK 5-BLACK 4-RED 11-RED 8-BLACK 14-BLACK 15-RED
中序遍历: 1-BLACK 2-RED 4-RED 5-BLACK 7-BLACK 8-BLACK 11-RED 14-BLACK 15-RED
后序遍历: 1-BLACK 4-RED 5-BLACK 2-RED 8-BLACK 15-RED 14-BLACK 11-RED 7-BLACK
删除元素5后:
先序遍历: 7-BLACK 2-RED 1-BLACK 4-BLACK 11-RED 8-BLACK 14-BLACK 15-RED
中序遍历: 1-BLACK 2-RED 4-BLACK 7-BLACK 8-BLACK 11-RED 14-BLACK 15-RED
后序遍历: 1-BLACK 4-BLACK 2-RED 8-BLACK 15-RED 14-BLACK 11-RED 7-BLACK