数据结构:红黑树理论

引言

我想本篇文章红黑树的故事应该从一个实际的应用讲起。如果我们选择用AVL树来存储数据,会有几个缺点:

首先AVL树的条件太过于苛刻,平衡系数如果大于2,那么我们就需要进行调整,也就是说,如果运气不是很好,我们只要插入两个数,我们就需要调整一次二叉树,很浪费时间。所以我们想要放宽这个条件。放宽这个条件有两个做法,一个是把平衡系数调大,一个是让这个树变成完全二叉树,尽量不去调整二叉树,每个结点可以存放多个数据。

而方法二就是我们的B树。什么是B树,就是一个结点可以存放多个数据,如图:

而我们的红黑树,就是把B树变成二叉树,而这里我们只变化2-3树和2-3-4树。

什么是2-3树,什么是2-3-4树?

拿2-3-4树举例子:

一棵树里面结点有三种类型

1、结点的度为2,可以存储1个数据

2、结点的度为3,可以存储2个数据

3、结点的度为4,可以存储3个数据

因为如果结构太复杂了,2-3-4-5-6。。。那样子也不好变化,所以我们的红黑树只包含2-3树和2-3-4树。

红黑树

红黑树的本质就是B树,它要把B树变成二叉树,所以要把数据不断的往下拆开。但是为什么我们需要分颜色,其实就是因为如果我们要还原成B树,我们需要直到我们那些结点是原来的结点,那些结点是被拆分开的,而原来的结点是黑色,被拆分的结点是红色的。

所以我们对于红黑树,我们可以得到一些性质,这些性质也十分重要:

1、因为根节点不可能是被拆分开的,所以根节点一定是黑色的

2、我们在红黑树里面,把叶子节点叫做失败结点,也就是nullptr结点,可能和我们之前学的结点的意义有些不一样,而红黑树里面的叶子节点一定是黑色的。

3、我们红颜色的来源是由黑节点拆分开的,所以红节点不可能和红节点在一起,因为如果红节点和红节点待在了一起,那下面哪个红节点是由谁拆分开的呢?如果是由上面那一层,那么那一层就应该是黑色的。但是黑色和黑色可以呆在一起,这也比较好理解,没有拆分数据嘛~~

4、一个结点到所有叶子结点的所经历的黑节点数量都相同。红黑树的本质就是B树,而B树的本质是完全二叉树,我们拆开完全二叉树的时候,是不断的往下增加红色的结点,不会有任何黑色结点的增加,所以自然而然,经过的黑色结点数量一样。

5、满足二叉排序树的顺序性。

所以说了半天,其实大家也发现了,红色结点的出现根本不影响黑色结点的本来性质,因为红色节点就是由黑色结点拆分出来的,而标记颜色也仅仅只是为了更方便合并回去。

6、结点的黑高(bh):从某个结点出发,到叶子结点经过的黑色结点(起点不算)

这个概念很容易和树高搞混,因为树的高度是不计算nullptr这个结点的,但是要计算起点,也就是根节点。

所以整个红黑树的黑高就是B树的树高。因为红色结点就是拆分出来的,根本不影响B树本身的性质。

7、那红黑树也有它自己的平衡性。

最长的黑高不可以超过最短的黑高的两倍。理解也非常的简单,假设一个B树一边是一个不拆分,也就是这个路径上根本没有红色节点的出现,而另一边全部拆开,得到红色的结点数量和黑色结点的数量相同

8、红黑树的高度也有所限制,一下是推到过程

总结(红黑树的应用)

Linux的CPU调度算法(完全公平算法)

Linux的epoll多路复用

这主要是因为红黑树对于平衡树的限制条件放宽了,所以可以减少调整的次数,来满足对于更多数据的存储。

本篇文章主要是对于红黑树的性质做了一个陈述,而对于红黑树的代码,会在之后的文章中慢慢呈现出来

相关推荐
炸膛坦客6 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
旖-旎6 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
Henry Zhu1237 小时前
C++中的特殊成员函数与智能指针
c++
_wyt0019 小时前
多重背包问题详解
c++·背包dp
Ljwuhe10 小时前
C++——多态
开发语言·c++
延凡科技11 小时前
多场景落地复盘:端边云架构无人机智能巡检系统设计与实践
大数据·数据结构·人工智能·科技·架构·无人机·能源
越甲八千11 小时前
STL stack为何没有迭代器
c++
从零开始的代码生活_12 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸12 小时前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
GIS阵地13 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis