红黑树中nil结点_什么是红黑树,一篇文章解决所有疑惑~~

400dfdb70823b6987e79b4cddcfd4b23.png

先来自问几个问题:

什么是红黑树?

为什么要有红黑树?

红黑树RBT与平衡二叉树AVL如何选择?

一颗红黑树是如何保持平衡的?

什么是一颗红黑树的黑高(Black Height)?

为什么一颗红黑树的所有操作时间复杂度都是O(logn)?

红黑树有什么应用呢?

本文中你都将找到答案

需要你清楚二叉排序树BST还有AVL树!不懂的看下面图文

图解:什么是二叉排序树?​mp.weixin.qq.com
0604cd886fe1a2fb8d6b194d35127e0c.png
图解:什么是AVL树?​mp.weixin.qq.com
27a50de0dcbcd448552d2dfa343f08ae.png
图解:什么是AVL树?(删除总结篇)​mp.weixin.qq.com
c346012379642d7a80bafd2dd79aac78.png

接下来看看红黑树的精髓所在?如果你的基础比较好(对什么是黑高、为什么要有红黑树,红黑树RBT与平衡二叉树AVL有何区别,如何选择?红黑树是如何保持平衡的?都理解),直接看最后面部的内容!要不就耐心自上而下看下去

02a4de68f93e9094c5bdca5829132ddc.png

1b7c36e20fd90b7a1a4010fb2be13ee6.png

b6c17f9de2c2d316831e6d0e017a4854.png

1d5389eee592fe03f01b5dda09f4425b.png

c889e9223e12c28bd4b1c5a0badce8fc.png

什么是红黑树?

红黑树(Red Black Tree)是一颗自平衡(self-balancing)的二叉排序树(BST),树上的每一个结点都遵循下面的规则(特别提醒,这里的自平衡和平衡二叉树AVL的高度平衡有别):

  1. 每一个结点都有一个颜色,要么为红色,要么为黑色;
  2. 树的根结点为黑色;
  3. 树中不存在两个相邻的红色结点(即红色结点的父结点和孩子结点均不能是红色);
  4. 从任意一个结点(包括根结点)到其任何后代 NULL 结点(默认是黑色的)的每条路径都具有相同数量的黑色结点。

a2922ec8cf17d12e614f1acf3826122e.png

这就是一颗典型的红黑树,树中的每个结点的颜色要么是黑色,要么是红色;根结点 6 为黑色结点;树中不存在两个相邻的红色结点,比如结点 15 为红色结点,其父亲节点 6 与两个孩子结点就一定是黑色,而不能是红色; 从结点到其后代的 NUll结点 的每条路径上具有相同数目的黑色结点,比如根结点 6 到其左子树的 NULL结点 包含三个黑色结点,到其右子树所有的 NULL 结点也包含三个黑色结点。 可能还不够清晰,为此我对上图做了修改为所有默认为黑色的 NULL 结点给了一个标记。

bc00327ea7fb2a159cb725a130ebfeed.png

现在解释规则的第四条简直不能再清晰了!比如根结点 6 到 NULL结点 a 的路径 6→2→a 上的黑色结点为 3 个,从根结点 6 到结点 c 的路径 6→15→10→9→c 中包含的黑色结点个数也是 3 个,同理从根结点 6 到其他所有 NULL结点 的黑色结点数都是 3 。再举个栗子,从红色结点 15 到NULL结点 d 的路径 15→18→g 包含 2 个黑色结点,到NULL结点 c 的路径 15→10→9→c 也包含黑色结点 2 个,从结点 15 到其所有后代的 NULL结点的 黑色结点数目都是 2

632ff8a3342ee60a5f82805954690b3e.png

dbef90d297991d9c9785e3ed2995de77.png

6393b7f80f1d7022ba7d438e6243e5b7.png

为什么要有红黑树?

大多数二叉排序树BST的操作(查找、最大值、最小值、插入、删除等等)都是

的时间复杂度,h 为树的高度。但是对于斜树而言(BST极端情况下出现),BST的这些操作的时间复杂度将达到 ​
。为了保证BST的所有操作的时间复杂度的上限为 ​
,就要想办法把一颗BST树的高度一直维持在
,而红黑树就做到了这一点,红黑树的高度始终都维持在
,n 为树中的顶点数目。

8a143fadac299b5814a3049b5c02cfb5.png

3d429869680fd4542f3b87ba3c4f56a4.png

红黑树RBT与平衡二叉树AVL比较:

AVL 树比红黑树更加平衡,但AVL树在插入和删除的时候也会存在大量的旋转操作。所以当你的应用涉及到频繁的插入和删除操作,切记放弃AVL树,选择性能更好的红黑树;当然,如果你的应用中涉及的插入和删除操作并不频繁,而是查找操作相对更频繁,那么就优先选择 AVL 树进行实现。

一颗红黑树是如何保持平衡的?

下面举一个简单但是很经典的例子,包含3个结点的单链是不可能出现在红黑树当中的。 关于这一点,我们可以自己绘制一条单链,然后尝试为其着色,然后判断是否是一颗红黑树证明这一点。

6868ccd7b4440cf7636abf1542c44049.png

从上图中可以发现,将根结点 9 涂黑色,其他结点分四种情况着色,结果都不满足红黑树的性质要求。唯一的办法就是调整树的高度,下面提供两种可行的设计方案:

0566fdb3aed843e7dcc57616fa6d8f51.png

上面的这个例子算是对红黑树维持平衡的初探,接着再看两个重要的概念:

什么是一颗红黑树的黑高(Black Height)?

在一颗红黑树中,从某个结点 x 出发(不包含该结点)到达一个叶结点的任意一条简单路径上包含的黑色结点的数目称为 黑高 ,记为 bh(x)

51d6553936ec6ec275bf9234ee573765.png

c7e03a1696e3151e8cae05c0401349da.png

3a6289a6d98e0fe63519603b0d2dda64.png

计算结点 6 的黑高,从结点 6 到结点 c 的路径是 6→15→10→9→c ,其中黑色结点为 6、10、c ,但是在计算黑高时,并不包含结点本身,所以从结点 6 到结点 c 的路径上的黑色结点个数为 2 ,那么 bh(6)=2 ;从结点 15 到结点 c 的路径为 15→10→9→c ,其中黑色结点为 10、c ,所以从结点 15 到结点 c 的路径上黑色结点数目为 2bh(15)=2

红黑树的黑高则为其根结点的黑高。根据红黑树的性质 3、4,一颗红黑树的黑高 bh >= h/2

Number of nodes from a node to its farthest descendant leaf is no more than twice as the number of nodes to the nearest descendant leaf. 从一个结点到其最远的后代叶结点的顶点数目不会超过从该结点到其最近的叶结点的结点数目的两倍。

这句话的意思就是公式

​ ,其中黑高
bh 就表示从根结点 6 到离它最近的叶结点 2 包含的结点数 2 ,而 h 则表示从根结点 6 到其最远的叶结点 9 所包含的结点数目 4 ,显然这一公式是合理的。

157255f97cb658684e167f6bded5535e.png

99fee544ca6209df07286bbe3bde5bca.png

引理:一棵有n个内部结点的红黑树的高度 h <= 2lg(n+1)。

关于算法导论中的证明,就不再这里显摆了,我们用一种更直观的方式来看一下这个问题。

首先我们将下图中的所有红色结点合并到其黑色父结点

26369ed6323b3972d755e9479d301489.png

合并动画演示:

3c3bfc1d6c28f562b7109435b32ee09b.gif

合并后的结果:

5728e7d63e1dd8654cbe6d17d60eaa0b.png

也就是刚才的合并产生了一颗 2-3-4 树,这棵树中的每一个结点有2、3 或者 4 个孩子结点。而一颗 2-3-4 树的叶结点有着相同的深度

.

245ab8a0cbf9f7a937ef8e7121adf202.png

由于从根结点到任何一个叶结点的路径上至多只有高度

的一半的红色结点数目,所以可以得到 ​ 的结论。

对于一颗有

个叶子结点的2-3-4 树而言,可以依次得到如下结论:

所以对于一颗有 ​

个结点的红黑树而言,不论查找、删除、查找和最大值、最小值等等的时间复杂度都是 ​
.

红黑树有什么应用呢?

  1. 大多数自平衡BST(self-balancing BST) 库函数都是用红黑树实现的,比如C++中的map 和 set (或者 Java 中的 TreeSet 和 TreeMap)。
  2. 红黑树也用于实现 Linux 操作系统的 CPU 调度。完全公平调度(Completely Fair Scheduler)使用的就是红黑树。

下图来自于为英文的维基百科(该图为Linux的内核图)。

ae11860a04d8d4baa6b626b63739c8f5.png

b352a715b894a314262bed64fca9f14f.png

ed3c629cafe823515950fd0441f6b5f6.png

4feeeb7e277f6d3e3c2a8cd9476a0863.png

5770ad98d4bd2ebbd6243f1bfaa428b5.png

ce3689342925f461a5717e56a31a951a.png
欢迎持续关注景禹

如果你觉得这篇内容对你挺有启发,还请帮我两个忙,让更多的人看到这篇文章:

1、点赞,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)

2、关注公众号「景禹」,专注于写数据结构与算法与计算基础,保证让你看完有所收获,不信你打我,已有 70篇数据结构与算法的原创文章,欢迎来阅览。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值