红黑树的插入

5 篇文章 0 订阅
2 篇文章 0 订阅

上回说到, avl 树的插入 -> 我们可以发现avl 树为了保持平衡 多次进行旋转, 其实很费时  -> avl很适合进行数据直接的查找, 但不适合插入太多的数据

so 我们讲解一下红黑树 我猜应该很多人很好奇这棵树 (比如我, 最开始接触 Java 某个类 底层是红黑树 我就很好奇了)

红黑树 也是 二叉搜索树, 接近平衡(最长路径不超过最短路径二倍), 新增加一个存储位来放置颜色(红色, 黑色), 一个节点是红色的它的两个孩子节点就要是黑色的(无2个连续的红色节点), 每一条简单路径上的黑色节点数相同

 红黑树的插入

最开始形如搜索二叉树 之后调整颜色

最开始的节点初始设置色为红色 -> 如果是黑色(每一条简单路径上的黑色节点数相同) 你需要继续插入节点 但是红色->去调整颜色

谈论下调整颜色的情况 parent == grandFather.left

 

 另一个else这个情况的条件则是相反 parent == grandFather.right

public class RBTree {

    static class RBTreeNode{
        public RBTreeNode left;
        public RBTreeNode right;
        public RBTreeNode parent;
        public int val;
        public COLOR color;

        public RBTreeNode(int val){
            this.val = val;
            // 默认红色 不然新增为黑色 有求路径黑色节点数目相同  设置红色这个到时候可以调颜色
            this.color = COLOR.RED;
        }
    }
    public RBTreeNode root;

    public boolean insert(int val){
        RBTreeNode node = new RBTreeNode(val);
        if(root==null){
            root = node;
            root.color = COLOR.BLACK;
            return true;
        }
        RBTreeNode parent = null;
        RBTreeNode cur = root;
        while (cur != null){
            if (cur.val > val){
                parent = cur;
                cur = cur.left;
            } else if(cur.val == val){
                return false;
            } else {
                parent = cur;
                cur = cur.right;
            }
        }
        if(val>parent.val){
            parent.right = node;
            node.parent = parent;
        } else {
            parent.left = node;
            node.parent = parent;
        }
        cur = node;

        // 调整
        while (parent!= null && parent.color==COLOR.RED){
            RBTreeNode grandFather = parent.parent;
            if(parent == grandFather.left){
                RBTreeNode uncle = grandFather.right;
                if (uncle!=null && uncle.color==COLOR.RED){
                    parent.color=COLOR.BLACK;
                    uncle.color=COLOR.BLACK;
                    grandFather.color=COLOR.RED;
                    cur = grandFather;
                    parent = cur.parent;
                } else {

                    if(cur==parent.right){
                        rotateLeft(parent);
                        RBTreeNode swap = cur;
                        cur = parent;
                        parent = swap;
                    }

                    rotateRight(grandFather);
                    parent.color = COLOR.BLACK;
                    grandFather.color = COLOR.RED;
                }
            } else {
                RBTreeNode uncle = grandFather.left;
                if (uncle!=null && uncle.color==COLOR.RED){
                    parent.color=COLOR.BLACK;
                    uncle.color=COLOR.BLACK;
                    grandFather.color=COLOR.RED;
                    cur = grandFather;
                    parent = cur.parent;
                } else {

                    if(cur==parent.left){
                        rotateRight(parent);
                        RBTreeNode swap = cur;
                        cur = parent;
                        parent = swap;
                    }

                    rotateLeft(grandFather);
                    parent.color = COLOR.BLACK;
                    grandFather.color = COLOR.RED;
                }

            }
        }

        root.color = COLOR.BLACK;
        return true;
    }

    private void rotateRight(RBTreeNode parent) {
        RBTreeNode subL = parent.left;
        RBTreeNode subLR = subL.right;

        parent.left = subLR;
        subL.right = parent;
        if(subLR!=null) {
            subLR.parent = parent;
        }
        RBTreeNode pParent = parent.parent;
        parent.parent = subL;

        // 看是不是根节点
        if(parent == root){
            root = subL;
            root.parent = null;
        } else {
            // 不是根节点 看是左子树还是右子树
            if(parent == pParent.left){
                pParent.left = subL;
            } else {
                pParent.right = subL;
            }
            subL.parent = pParent;
        }
    }

    private void rotateLeft(RBTreeNode parent) {
        RBTreeNode subR = parent.right;
        RBTreeNode subRL = subR.left;

        subR.left = parent;
        parent.right = subRL;

        if(subRL!=null){
            subRL.parent = parent;
        }
        RBTreeNode pParent = parent.parent;
        parent.parent = subR;
        if(parent==root){
            root=subR;
            root.parent = null;
        } else {
            if(pParent.left==parent){
                pParent.left = subR;
            } else {
                pParent.right = subR;
            }
            subR.parent = pParent;
        }
    }
}
public enum COLOR {
    RED,BLACK
}

okkk 所以红黑树 不用那么辛苦的维护平衡 有的时候只需要左旋/右旋~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值