news 2026/5/4 8:02:29

C++笔记-红与黑的博弈:一棵二叉树的“自律”与“平衡”之道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++笔记-红与黑的博弈:一棵二叉树的“自律”与“平衡”之道

1.u存在且为红色

2.u不存在

3.u存在且为黑色

4.2.1情况1:变色

c为红,p为红,g为⿊,u存在且为红,则将p和u变⿊,g变红。在把g当做新的c,继续往上更新。

分析:因为p和u都是红⾊,g是⿊⾊,把p和u变⿊,左边⼦树路径各增加⼀个⿊⾊结点,g再变红,相当于保持g所在⼦树的⿊⾊结点的数量不变,同时解决了c和p连续红⾊结点的问题,需要继续往上更新是因为,g是红⾊,如果g的⽗亲还是红⾊,那么就还需要继续处理;如果g的⽗亲是⿊⾊,则处理结束 了;如果g就是整棵树的根,再把g变回⿊⾊。

情况1只变⾊,不旋转。所以⽆论c是p的左还是右,p是g的左还是右,都是上⾯的变⾊处理⽅式。

这就是第一种情况:u存在且为红的处理方式,下面我们来看这种情况的示意图:

在这种情况中我们是不需要旋转的,只需要变色即可。当然,这只是其中最简单的一种情况,所以我们一般看抽象图。

和上一篇AVL树一样,我们来看一看某些情况来理解为什么我们要看抽象图。

这是hb=0的情况。

这是hb=1的情况。

这是hb=2的情况。

这里可以看出,相比hb=1而言仅仅只多了一个hb,就多了非常多种情况,所以说我们要要看抽象图。

下面我们就实现下变色这种情况的代码:

在控制循环条件中我们不仅要判断此时parent是否为空,还要判断此时的parent是红色才能进入循环,如果parent是黑色就不需要更新颜色。

这里我们先写parent在grandfather的左边的情况,将三种情况写完,parent在右边直接复制过去,再改些值就可以。

里面的代码就是根据我们上面写的变色过程来完成,并且在完成一次变色后,要继续向上判断。

4.2.2情况2:单旋+变色

c为红,p为红,g为⿊,u不存在或者u存在且为⿊,u不存在,则c⼀定是新增结点,u存在且为⿊,则 c⼀定不是新增,c之前是⿊⾊的,是在c的⼦树中插⼊,符合情况1,变⾊将c从⿊⾊变成红⾊,更新上来的。

分析:p必须变⿊,才能解决,连续红⾊结点的问题,u不存在或者是⿊⾊的,这⾥单纯的变⾊⽆法解 决问题,需要旋转+变⾊。

如果p是g的左,c是p的左,那么以g为旋转点进⾏右单旋,再把p变⿊,g变红即可。p变成这颗树新的根,这样⼦树⿊⾊结点的数量不变,没有连续的红⾊结点了,且不需要往上更新,因为p的⽗亲是⿊⾊还是红⾊或者空都不违反规则。

如果p是g的右,c是p的右,那么以g为旋转点进⾏左单旋,再把p变⿊,g变红即可。p变成这颗树新的根,这样⼦树⿊⾊结点的数量不变,没有连续的红⾊结点了,且不需要往上更新,因为p的⽗亲是⿊⾊还是红⾊或者空都不违反规则。

根据上面的规则我们来写情况2的代码:

右单旋我们在AVL树那一章节已经讲过,这里就不过多赘述,红黑树中的右单旋与其不同的是不需要判断平衡因子的情况了。

剩下的就和AVL树中的一样,最后将parent和grandfather变色即可。

最后我们来看一下单旋+变色的过程。

4.2.3情况3:双旋+变色

c为红,p为红,g为⿊,u不存在或者u存在且为⿊,u不存在,则c⼀定是新增结点,u存在且为⿊,则 c⼀定不是新增,c之前是⿊⾊的,是在c的⼦树中插⼊,符合情况1,变⾊将c从⿊⾊变成红⾊,更新上来的。

分析:p必须变⿊,才能解决,连续红⾊结点的问题,u不存在或者是⿊⾊的,这⾥单纯的变⾊⽆法解决问题,需要旋转+变⾊。

如果p是g的左,c是p的右,那么先以p为旋转点进⾏左单旋,再以g为旋转点进⾏右单旋,再把c变

⿊,g变红即可。c变成这颗树新的根,这样⼦树⿊⾊结点的数量不变,没有连续的红⾊结点了,且不需要往上更新,因为c的⽗亲是⿊⾊还是红⾊或者空都不违反规则。

如果p是g的右,c是p的左,那么先以p为旋转点进⾏右单旋,再以g为旋转点进⾏左单旋,再把c变

⿊,g变红即可。c变成这颗树新的根,这样⼦树⿊⾊结点的数量不变,没有连续的红⾊结点了,且不需要往上更新,因为c的⽗亲是⿊⾊还是红⾊或者空都不违反规则。

我们根据上面的规则来写情况3的代码:

经过上面的单旋其实我们也可以看出,红黑树的单旋和双旋情况和AVL树是很类似的,无非就是需要旋转的条件不同,但是一旦要旋转,结点的分布是一样的。

旋转过后改变cur和grandfather的颜色即可。

最后我们看一下双旋+变色的过程。

下面就是parent在grandfather右边的代码:

这里要注意的是我们在旋转过后就要break来停止循环,否则会出问题的。

这里可能有人会有一个疑惑:那经过上述的操作后,如果根结点被改为红色呢?

我相信在讲上面的操作中,有人疑惑我为什么不判断根结点是否被改变,因为我们这里可以暴力解决:

我不管你中间经过了什么步骤,在循环结束时,我直接对根结点的_col进行修改,将其改为黑色,这样就完美解决上面的问题,并且简单又简洁。

5.红黑树的判断

我们在写完了红黑树,如何判断它是否是红黑树呢?

在AVL树的章节,我们是通过判断高度差来判断是否是AVL树,而在红黑树中显然我们不能这样判断。

那么能不能根据颜色来判断呢?

答案也不能,在红黑树中,我们要判断的话要根据红黑树的四条规则来判断,这样才严谨。

我们判断的思路是:先找出任意一条路径的黑色节点的个数,在遍历其他路径判断黑色节点的个数是否相同,并在遍历的途中判断有没有连续的红色结点,这样就能兼顾红黑树的四条规则。

在上面的代码中,我以最左边的路径为标准,来检查左右子树是否都为红黑树。

其中要注意的就是检查有无两个连续的红色结点时,要找其parent,原因上面我也写了,最后如果左右子树都是红黑树返回true,不满足就返回false。

最后我们来看一下递归过程的示意图。

还有一些像:Find,Inorder,Size和Height这些函数和AVL树那篇中的一样,这里就不写了。而红黑树的删除和AVL树的删除一样都不在讲解,理由也是一样的,对于两者而言,我们通过插入了解两者是如何控制平衡的即可,熟悉控制平衡的过程,都有哪些情况。

https://www.dongchedi.com/article/7600833157193253401
https://www.dongchedi.com/article/7600834099257016856
https://www.dongchedi.com/article/7600832447063999000
https://www.dongchedi.com/article/7600832867085713945
https://www.dongchedi.com/article/7600831262563598873
https://www.dongchedi.com/article/7600831402183311897
https://www.dongchedi.com/article/7600832061917905470
https://www.dongchedi.com/article/7600832733291594264
https://www.dongchedi.com/article/7600831880816132632
https://www.dongchedi.com/article/7600831372500140568
https://www.dongchedi.com/article/7600830983973110297
https://www.dongchedi.com/article/7600830989874577944
https://www.dongchedi.com/article/7600829992859484697
https://www.dongchedi.com/article/7600831200579633688
https://www.dongchedi.com/article/7600828893398254104
https://www.dongchedi.com/article/7600829947162739225
https://www.dongchedi.com/article/7600830440379204158
https://www.dongchedi.com/article/7600830705475813950
https://www.dongchedi.com/article/7600829156548837913
https://www.dongchedi.com/article/7600828482650194457
https://www.dongchedi.com/article/7600829257937584702
https://www.dongchedi.com/article/7600829728349684248
https://www.dongchedi.com/article/7600828048296083993
https://www.dongchedi.com/article/7600829419913511486
https://www.dongchedi.com/article/7600826526896112152
https://www.dongchedi.com/article/7600825958186648089
https://www.dongchedi.com/article/7600826072481055257
https://www.dongchedi.com/article/7600826004273431065
https://www.dongchedi.com/article/7600826285178536472
https://www.dongchedi.com/article/7600825958186418713
https://www.dongchedi.com/article/7600825908014252569
https://www.dongchedi.com/article/7600826379294704190
https://www.dongchedi.com/article/7600826004273267225
https://www.dongchedi.com/article/7600826379294573118
https://www.dongchedi.com/article/7600825908014154265
https://www.dongchedi.com/article/7600825816129765913
https://www.dongchedi.com/article/7600826257907466814
https://www.dongchedi.com/article/7600825708680135193
https://www.dongchedi.com/article/7600826257907270206
https://www.dongchedi.com/article/7600825908013924889
https://www.dongchedi.com/article/7600825653575303705
https://www.dongchedi.com/article/7600763089105469977
https://www.dongchedi.com/article/7600825816129471001
https://www.dongchedi.com/article/7600825816129339929
https://www.dongchedi.com/article/7600761478211224089
https://www.dongchedi.com/article/7600826159441904190
https://www.dongchedi.com/article/7600763029579743806
https://www.dongchedi.com/article/7600763312351101465
https://www.dongchedi.com/article/7600755747886334488
https://www.dongchedi.com/article/7600758147854549566
https://www.dongchedi.com/article/7600825603486876185
https://www.dongchedi.com/article/7600711725914014233
https://www.dongchedi.com/article/7600708729394217534
https://www.dongchedi.com/article/7600825816129569305

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 5:35:23

HY-Motion 1.0企业应用:为元宇宙社交平台批量生成用户个性化动作

HY-Motion 1.0企业应用:为元宇宙社交平台批量生成用户个性化动作 1. 这不是“动效插件”,而是能批量造动作的AI产线 你有没有想过,一个拥有百万用户的元宇宙社交平台,每位用户都希望自己的虚拟形象能做出独一无二的动作——挥手…

作者头像 李华
网站建设 2026/5/3 8:59:50

超简单方法:几行代码实现Linux开机任务自动化

超简单方法:几行代码实现Linux开机任务自动化 你有没有遇到过这样的情况:写好了一个监控脚本、数据采集程序,或者一个轻量级Web服务,每次重启服务器后都要手动运行一次?反复输入python monitor.py或./start.sh不仅麻烦…

作者头像 李华
网站建设 2026/5/3 6:47:09

BSHM模型实测:复杂背景人像分离效果惊艳

BSHM模型实测:复杂背景人像分离效果惊艳 你有没有遇到过这样的场景:一张人站在熙攘街景、茂密树林或杂乱室内的人像照片,想快速抠出干净人像换背景,结果用传统工具反复擦、反复调,半小时过去还留着毛边?或…

作者头像 李华
网站建设 2026/5/1 18:00:06

Fillinger图形填充技术全解析:从原理到实战应用

Fillinger图形填充技术全解析:从原理到实战应用 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 一、初识Fillinger:设计效率提升工具 Fillinger作为Adobe I…

作者头像 李华
网站建设 2026/5/2 21:22:51

颠覆传统窗口管理:Loop带来的效率革命

颠覆传统窗口管理:Loop带来的效率革命 【免费下载链接】Loop MacOS窗口管理 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 你是否正经历窗口管理的效率困境? 每天有多少时间浪费在拖拽窗口、调整大小上?据统计&#xff0c…

作者头像 李华