Java实现红黑树

参考算法导论的伪代码写出,留个纪念,重点是要多画图理解

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值