merger红黑树

package cn.lyf;

public class rbt {
    Node root;

    class State {
        boolean bal;
        Node cur;

        public State(Node cur, boolean bal) {
            this.bal = bal;
            this.cur = cur;
        }
    }

    public void ins(int k) {
        root = ins(root, k);
        root.red = false;
    }

    public void del(int k) {
        root = del(root, k).cur;
    }

    Node dyeing(Node n) {
        if (n.red)
            return n;
        Boolean[] lefts = new Boolean[2];
        if (!canDyeing(n, lefts))
            return n;
        
        if (lefts[0] ^ lefts[1])
            n.set(lefts[0], roate(n.get(lefts[0]), lefts[0]));
        n = roate(n, !lefts[0]);
        n.red = true;
        n.L.red = n.R.red = false;
        return n;
    }

    static boolean canDyeing(Node n, Boolean[] lefts) {
        if (n.L != null && n.L.red && n.L.R != null && n.L.R.red) {
            lefts[0] = true;
            lefts[1] = false;
            return true;
        }
        if (n.R != null && n.R.red && n.R.L != null && n.R.L.red) {
            lefts[0] = false;
            lefts[1] = true;
            return true;
        }
        if (n.R != null && n.R.red && n.R.R != null && n.R.R.red) {
            lefts[0] = lefts[1] = false;
            return true;
        }
        if (n.L != null && n.L.red && n.L.L != null && n.L.L.red) {
            lefts[0] = lefts[1] = true;
            return true;
        }
        return false;
    }

    Node ins(Node n, int k) {
        if (n == null) {
            return new Node(null, k, null, true);
        }
        if (k == n.val)
            return n;
        if (k < n.val) {
            n.L = ins(n.L, k);
        } else {
            n.R = ins(n.R, k);
        }
        return dyeing(n);
    }

    Node doubleRoate(Node n, boolean a, boolean b) {
        if (a ^ b)
            n.set(a, roate(n.get(a), a));
        return roate(n, !a);
    }

    boolean canDyeing(Node n, boolean[] lefts, int i) {
        if (i == 2)
            return true;
        lefts[i] = false;
        if (n.R != null && canDyeing(n.R, lefts, i + 1))
            return true;
        lefts[i] = true;
        if (n.L != null && canDyeing(n.L, lefts, i + 1))
            return true;
        return false;
    }

    Node merge(Node a, Node b) {
        if (a == null || b == null)
            return a == null ? b : a;
        // 异色
        if (a.red ^ b.red) {
            if (a.red) {
                a.R = merge(a.R, b);
                return a;
            } else {
                b.L = merge(a, b.L);
                return b;
            }
        }
        a.R = merge(a.R, b.L);
        b.L = a;
        if (a.red) {
            if (a.R == null || !a.R.red)
                return b;
            return doubleRoate(b, true, false);
        }
        a.red = true;
        return dyeing(b);
    }

    State del(Node n, int k) {
        if (n == null)
            return new State(null, true);
        if (n.val == k) {
            Node t = merge(n.L, n.R);
            // 删除的是红色节点
            if (n.red)
                return new State(t, true);
            // 删除的是黑色节点
            // 合并后根节点为红色
            if (t != null && t.red) {
                t.red = false;
                return new State(t, true);
            }
            // 合并后根节点为null或黑色
            return new State(t, false);
        }
        State state = n.val > k ? del(n.L, k) : del(n.R, k);
        n.set(n.val > k, state.cur);
        state.cur = n;
        return balance(state, n.val > k);
    }

    Node roate(Node n, boolean left) {
        if (n == null)
            return null;
        Node t1 = n.get(!left), t2;
        if (t1 == null)
            return n;
        t2 = t1.get(left);
        n.set(!left, t2);
        t1.set(left, n);
        return t1;
    }

    State balance(State state, boolean left) {
        if (state.bal)
            return state;
        Node cur = state.cur, bro = cur.get(!left);
        // 1 // 左旋后和左子树交换颜色 // 对左子树再次调用情况2
        if (bro.red) {
            bro.red = false;
            cur.red = true;
            roate(cur, left);
            bro.set(left, balance(state, left).cur);
            return new State(bro, true);
        }
        // 2 //如果根节点为红色就平衡了 //把右子树设成红的,根节点设成黑的
        if (isBlack(bro.L) && isBlack(bro.R)) {
            state.bal = cur.red;
            cur.red = false;
            bro.red = true;
            return state;
        }
        // 3 //左旋,根节点和左右子树涂黑
        if (!isBlack(bro.get(!left))) {
            roate(cur, left);
            bro.red = cur.red;// 保持原色
            bro.L.red = bro.R.red = false;
            return new State(bro, true);
        }
        // 4 //右子树右旋,右子树变成情况3
        bro.red = true;
        bro.get(left).red = false;
        cur.set(!left, roate(bro, !left));
        return balance(new State(cur, false), left);
    }

    static boolean isBlack(Node n) {
        return n == null || !n.red;
    }
}

class Node {
    int val;
    boolean red;
    Node L, R;

    Node(int v) {
        val = v;
    }

    Node(Node L, int val, Node R, boolean red) {
        this.val = val;
        this.L = L;
        this.R = R;
        this.red = red;
    }

    Node get(boolean left) {
        if (left)
            return L;
        return R;
    }

    Node set(boolean left, Node v) {
        if (left)
            return L = v;
        return R = v;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值