数据结构:红黑树理论

引言

我想本篇文章红黑树的故事应该从一个实际的应用讲起。如果我们选择用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多路复用

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

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

相关推荐
Yolo_TvT1 小时前
C++:默认构造函数
c++
San813_LDD2 小时前
[数据结构]LeetCode学习
数据结构·算法·图论
小欣加油3 小时前
leetcode994 腐烂的橘子
数据结构·c++·算法·leetcode·bfs
.千余4 小时前
【C++】手写双向链表:list容器模拟实现
开发语言·c++·笔记·学习·其他
liulilittle4 小时前
过冲:拥塞控制的呼吸与盲行
linux·网络·c++·tcp/ip·计算机网络·tcp·通信
Felven4 小时前
B. Fair Numbers
数据结构·算法
ysu_03144 小时前
leetcode数据结构与算法1~4
c语言·数据结构·学习·算法·leetcode
小欣加油4 小时前
leetcode2574 左右元素和的差值
数据结构·c++·算法·leetcode·职场和发展
weixin_461769405 小时前
通过数组和队列构造二叉树方法(用于算法测试),C++ vector不能直接使用null
数据结构·c++·算法·vector·nullptr·null