红黑树

红黑树是一个中和二叉平衡查找树的树

1.红黑树性质

1.每个结点要么是红的要么是黑的。

2.根结点是黑的。

3.每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。

4.如果一个结点是红的,那么它的两个儿子都是黑的。(不能有两个红色节点相连)

5.对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。
推论:如果一个节点存在黑子节点,那么该结点肯定有两个子节点。
在这里插入图片描述

2.红黑树平衡

左旋、右旋、变色

在这里插入图片描述
左旋:旋上去的顶点的左子树,变为旋下去顶点的右子树
右旋:旋上去的顶点的右子树,变为旋下去顶点的左子树

在这里插入图片描述
在这里插入图片描述

3.红黑树查找

和二叉搜索树一样

4.插入

  1. 查找到插入的位置
  2. 插入后自平衡

插入的节点必须是红色节点

1.插入21结点 没破坏平衡

在这里插入图片描述

在这里插入图片描述

2、节点的key已存在,则直接覆盖掉值

在这里插入图片描述

在这里插入图片描述

3、插入节点的父节点为黑节点,直接插入不影响平衡在这里插入图片描述

在这里插入图片描述

4、插入节点父节点为红色

在这里插入图片描述

4.1叔叔节点存在且为红节点

在这里插入图片描述

4.2叔叔节点不存在或为黑节点,且插入节点的父亲节点是祖父节点的左子节点

在这里插入图片描述

4.2.1 插入节点为其父节点的左子节点

在这里插入图片描述
在这里插入图片描述

4.2.2 插入节点为其父节点的右子节点

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.3 反方向

在这里插入图片描述

4.3.1 插入节点为其父节点的右子节点

在这里插入图片描述
在这里插入图片描述

4.3.2 插入节点为其父节点的左子节点

在这里插入图片描述

例子:

在这里插入图片描述

总结:

在这里插入图片描述

红黑树插入操作

 static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
                                                    TreeNode<K,V> x) {
            //新节点默认为红色
            x.red = true;
            //xp表示为x的父节点,xpp表示x的祖父节点,xpp1表示xpp的左孩子节点,xppr表示xpp的右孩子节点
            for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
            //如果x没有父节点,则表示x是第一个节点,即根节点,根节点是黑色
                if ((xp = x.parent) == null) {
                    x.red = false;
                    return x;
                }
                //如果父节点不是红色(就是黑色,或者x没有祖父节点,则x是第二层节点,父节点是根节点,无需操作。)
                else if (!xp.red || (xpp = xp.parent) == null)
                    return root;
                 //如果父节点为红色
                 //如果x的父节点是祖父节点的左孩子
                if (xp == (xppl = xpp.left)) {
                //判断叔叔节点是不是红色的,红色就父节点叔叔节点变黑,祖父变红,还可能需要递归调整,接下来就调整x的祖父节点
                    if ((xppr = xpp.right) != null && xppr.red) {
                        xppr.red = false;
                        xp.red = false;
                        xpp.red = true;
                        x = xpp;
                    }
                    //没有叔叔节点和有叔叔是黑色的情况。。
                    else {
                        if (x == xp.right) {
                            root = rotateLeft(root, x = xp);
                            xpp = (xp = x.parent) == null ? null : xp.parent;
                        }
                        if (xp != null) {
                            xp.red = false;
                            if (xpp != null) {
                                xpp.red = true;
                                root = rotateRight(root, xpp);
                            }
                        }
                    }
                }
                else {
                    if (xppl != null && xppl.red) {
                        xppl.red = false;
                        xp.red = false;
                        xpp.red = true;
                        x = xpp;
                    }
                    else {
                        if (x == xp.left) {
                            root = rotateRight(root, x = xp);
                            xpp = (xp = x.parent) == null ? null : xp.parent;
                        }
                        if (xp != null) {
                            xp.red = false;
                            if (xpp != null) {
                                xpp.red = true;
                                root = rotateLeft(root, xpp);
                            }
                        }
                    }
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值