《算法导论》红黑树详解(二):Java实现Demo

《算法导论》红黑树详解(一):概念
《算法导论》红黑树详解(二):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
点赞