红黑树新增节点详解

二叉树、平衡二叉树

红黑树它是一种特殊的平衡二叉树,
假设你已经对二叉树、平衡二叉树的概念有了一定的了解,

二叉树和平衡二叉树的介绍,在
通过B+Tree平衡多叉树理解InnoDB引擎的聚集和非聚集索引
有着比较清晰的描述。

旋转

有必要对平衡二叉树的旋转做一下介绍:

左旋
对y节点进行左旋:
将y节点的右子节点x作为新的父节点;
将y节点作为x节点的左子节点;
将x节点的左子节点作为y节点的右子节点。

右旋
对x节点进行左旋:
将x节点的左子节点y作为新的父节点;
将x节点作为y节点的右子节点;
将y节点的右子节点作为x节点的左子节点。
在这里插入图片描述
有动图大家感受一下
请添加图片描述
请添加图片描述

红黑二叉树

为什么有红黑二叉树,
平衡二叉树有着严格的平衡限制,任何一个节点左右子树的高度差不能超过1,
否则就失衡,需要旋转保持平衡,在频繁地插入或者删除节点的一些场景中,
大量的旋转操作会非常影响性能,红黑树通过牺牲严格的平衡,换来少量的旋转操作,
整体性能要优于平衡二叉树。

我们先来看下红黑树长什么样子:
在这里插入图片描述
算法导论中对红黑树的约束条件:
1、节点不是红的,就是黑的;
2、根节点是黑的;
3、叶节点是黑的;
4、父子节点不能同时是红的,任何分支上都不能出现两个连续的红色节点;
5、任意节点到叶节点的所有路径上,包含的黑色节点数量相同,即相同的黑色高度。

说明:
4、5保证了红黑树的大致平衡,
黑色高度为3时,
最短路径:黑→黑→黑=2;
最长路径:黑→红→黑→红→黑=4。

默认新插入的节点为红色,
因为红色不会影响路径上黑色节点的数量。

应用
Java中treemap、treeset都使用红黑树作为底层数据结构,
jdk1.8开始,hashmap也引入了红黑树。

在Java的实现中,使用黑色的空节点null来作为叶子节点。

平衡操作

红黑树新增节点
红黑树新增节点,可能会影响到红黑树的平衡,所以需要在进行平衡操作。

我们先约定一下关系:
在这里插入图片描述

新增节点

1、子节点为根节点

子节点开始是红的,但它是根节点,需要涂黑。
在这里插入图片描述

2、父节点为黑

无需其它操作。
在这里插入图片描述

3、父节点为红、叔节点为红

需要将叔、父节点涂黑,祖父节点涂红,然后把祖父节点作为新的子节点,往上递归执行平衡操作。
在这里插入图片描述

4、父节点为红、叔节点为黑

4.1、祖父-父、父-子方向一致
4.1.1、同左

父节点是祖父节点的左子节点,子节点是父节点的左子节点。

以祖父节点为支点进行右旋,然后将父节点涂黑、祖父节点涂红。

父节点涂黑是因为要涂为原祖父节点的黑色(往上兼容祖父节点的父节点),
而祖父节点涂红则是因为右旋后,经过叔节点的路径的黑色节点数量加一,涂红进行数量平衡,下同。
在这里插入图片描述

4.1.2、同右

父节点是祖父节点的右子节点,子节点是父节点的右子节点。

以祖父节点为支点进行左旋,然后将父节点涂黑,祖父节点涂红。
在这里插入图片描述

4.2、祖父-父、父-子方向不一致
4.2.1、父节点左、子节点右

父节点是祖父节点的左子节点,子节点是父节点的右子节点。

以父节点为支点进行左旋,然后以父节点作为新的平衡节点,进行同左处理。
在这里插入图片描述

4.2.2、父节点右、子节点左

父节点是祖父节点的右子节点,子节点是父节点的左子节点。

以父节点为支点进行右旋,然后以父节点作为新的平衡节点,进行同右处理。
在这里插入图片描述

例子

新增节点:10、20、15、30、5、8。
在这里插入图片描述

参考文章:

路过的猪:彻底理解红黑树(二)之插入
晓之木初:红黑树详解
Just-Today:红黑树-Java实现
Geek_Ma:红黑树插入删除实例
面向c v编程:Hashmap底层实现原理(JDK1.8)(AVL树简介.红黑树的原理)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值