红黑树的插入自平衡

public class RBTree<T extends Comparable<T>>{

    private RBTNode<T> mRoot; //根节点

    private static final boolean RED = false;
    private static final boolean BLACK = true;

    public class RBTNode<T extends Comparable<T>> {
        boolean color;  //颜色
        T key;          //关键字
        RBTNode<T> left; //左孩子
        RBTNode<T> right; //右孩子
        RBTNode<T> parent; //父节点

        public RBTNode(T key, boolean color, RBTNode<T> parent, RBTNode<T> left, RBTNode<T> right){
            this.color = color;
            this.key = key;
            this.left = left;
            this.right = right;
            this.parent = parent;
        }
    }

    public void insert(T key){
        RBTNode<T> node = new RBTNode<>(key, RED, null, null, null);
        insertNode(node);
    }

    public void insertNode(RBTNode<T> node){
        int cmp;
        RBTNode<T> x = this.mRoot;
        RBTNode<T> y = null;

        //1.将红黑树当作一颗二叉查找树,将节点添加到二叉查找树中
        while(x != null){
            y = x;
            cmp = node.key.compareTo(y.key);
            if(cmp < 0){
                x = x.left;
            }else if(cmp > 0){
                x = x.right;
            }else{
                return;
            }
        }

        node.parent = y;
        if(y != null){
            cmp = node.key.compareTo(y.key);
            if(cmp < 0){
                y.left = node;
            }else{
                y.right = node;
            }
        }else {
            this.mRoot = node;
        }

        insertFixUp(node);
    }

    private void insertFixUp(RBTNode<T> node) {
        RBTNode<T> parent, gparent;
        while(((parent = node.parent) != null) && isRed(parent)){
            gparent = parent.parent;

            //若父节点是祖父节点的左孩子
            if(parent == gparent.left){
                //case 1条件:叔叔节点是红色
                RBTNode<T> uncle = gparent.right;
                if((uncle != null) && isRed(uncle)){
                    colorBlack(uncle);
                    colorBlack(parent);
                    colorRed(gparent);
                    node = gparent;
                    continue;
                }

                //case 2条件:叔叔是黑色,且当前节点是右孩子
                if(parent.right == node){
                    leftRotate(parent);
                    RBTNode<T> temp = node;
                    node  =  parent;
                    parent = temp;
                }

                //case3条件:叔叔是黑色,且当前节点是左孩子
                colorBlack(parent);
                colorRed(gparent);
                rightRotate(gparent);
            }else { //父节点是祖父节点的右孩子
                RBTNode<T> uncle =  gparent.left;
                if((uncle != null) && isRed(uncle)){
                    colorBlack(uncle);
                    colorBlack(parent);
                    colorRed(gparent);
                    node = gparent;
                    continue;
                }else{
                    //case1条件:加入的节点为左节点
                    if(parent.left == node){
                        rightRotate(parent);
                        RBTNode<T> temp = node;
                        node = parent;
                        parent = temp;
                    }

                    //case2条件:加入的节点为右节点
                    colorBlack(parent);
                    colorRed(gparent);

                    leftRotate(gparent);
                }
            }
        }

        //将根节点染成黑色
        colorBlack(this.mRoot);
    }

    public void delete(){

    }

    public void inOrder(){
        inOrderItem(this.mRoot);
    }

    private void inOrderItem(RBTNode<T> node){
        if(node != null){
            inOrderItem(node.left);
            System.out.println("node.key = " + node.key);
            inOrderItem(node.right);
        }
    }

    /**
     * 左旋
     * @param privot
     */
    private void leftRotate(RBTNode<T> privot){
        RBTNode<T> right = privot.right;
        right.parent = privot.parent;
        privot.right = right.left;
        if(right.left != null){
            right.left.parent = privot;
        }
        privot.parent = right;
        right.left = privot;
        if(right.parent == null){
            this.mRoot = right;
        }else {
            if(right.parent.left == privot){
                right.parent.left = right;
            }else {
                right.parent.right = right;
            }
        }
    }

    /**
     * 右旋
     * @param privot
     */
    private void rightRotate(RBTNode<T> privot){
        RBTNode<T> left = privot.left;
        left.parent = privot.parent;
        privot.left = left.right;
        if(left.right != null){
            left.right.parent = privot;
        }
        privot.parent = left;
        left.right = privot;
        if(left.parent == null){
            this.mRoot = left;
        }else {
            if(left.parent.left == privot){
                left.parent.left =  left;
            }else {
                left.parent.right = left;
            }
        }
    }

    /**
     * 染红色
     * @param node
     */
    private void colorRed(RBTNode<T> node){
        node.color = RED;
    }

    private void colorBlack(RBTNode<T> node){
        node.color = BLACK;
    }

    private boolean isRed(RBTNode<T> node){
        return !node.color;
    }

    private boolean isBlack(RBTNode<T> node){
        return node.color;
    }

    public static void main(String[] args) {
        RBTree<Integer> rbTree = new RBTree<>();
        rbTree.insert(1);
        rbTree.insert(1);
        rbTree.inOrder();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值