【数据结构】红黑树(Red-Black Tree)

前言

在上一篇博客中,我们学习了 AVL 树,为了保持绝对的平衡,它在插入和删除时会疯狂地进行左旋和右旋。

但在现代的Java集合框架中(如 TreeMapTreeSet,以及 Java 8 之后的 HashMap),并没有选择 AVL 树,而是选择了红黑树(Red-Black Tree)

一、为什么有了 AVL 树,还要红黑树?

AVL树的特点:任何节点的左右子树高度差绝对不能超过 1。这导致了一个致命问题:查询确实快了,但每次插入或删除数据时,为了维持这种极度的平衡,树结构需要极其频繁地进行旋转调整。

红黑树的诞生,就是为了解决这个痛点。 它是一种**"弱平衡"**的二叉查找树。它不再追求左右两边高度的绝对一致,它的平衡规则是通过"红黑规则"进行实现的。

红黑树特点:

是一个二叉查找树。

但是不是高度平衡的。

特有的红黑规则。

二、红黑树五大规则

  1. 节点非黑即红:每一个节点或是红色,或者是黑色的。
  2. 根节点必黑:根节点必须是黑色的。
  3. 叶子节点必黑:如果一个节点没有子节点或者父节点,则改节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的。
  4. 红必连黑: 如果一个节点是红色的,那么它的两个子节点必须都是黑色的。
  5. 黑高一致(最重要的一条): 从任意一个节点出发,走到其所有后代叶子节点(NIL)的简单路径上,包含的黑色节点数量必须完全相同

三、红黑树添加节点的规则

1.引例

默认颜色:添加节点默认是红色的(效率最高)。

若默认颜色是黑色,会发生什么:

此时违背了五大规则的最后一条:从任意节点出发走到其后代的叶节点的所有简单路径上黑色节点数量一样。

要把添加的18节点变成红色。

此时又有一个节点添加进来:

此时仍旧违背了第五条规则。

由上述例子可知,如果默认节点为黑色添加三个节点要调整两次

此时,如果待添加节点为红色:

添加第一个节点,为红色,违背了第二条规则:根节点必须是黑色。

再添加第二个节点18:

此时满足红黑树的五大规则,无需调整。

再添加第三个节点23:

仍旧满足红黑规则,无需调整。

由上述例子可知,如果默认节点为红色,添加三个节点要调整一次。

因此:添加节点默认是红色的(效率最高)。

2.添加规则

在上面的基础上加一些难度,现在要添加第四个节点22,

步骤是这样的:

1、发现违背了红色不能相连的规则。

2、添加节点非根 -> 父节点是红色 -> 叔节点为红色

3、将父节点设置为黑,再将叔叔节点设置为黑,祖父设为红。

4、祖父节点为根节点,需要再变回黑色

总结

红黑树之所以比 AVL 树增删快,就是因为它在冲突时优先选择变色,哪怕需要旋转,通常最多也只需要 3 次旋转就能搞定,而 AVL 树的旋转次数是不可控的

相关推荐
深邃-2 小时前
字符函数和字符串函数(2)
c语言·数据结构·c++·后端·算法·restful
bekote2 小时前
PTA基础编程题目集-6-11 求自定类型元素序列的中位数(简单解法)
数据结构·c++·算法
漫随流水13 小时前
c++编程:反转字符串(leetcode344)
数据结构·c++·算法
Titan202417 小时前
map和set的封装学习笔记
数据结构·c++
Yupureki17 小时前
《算法竞赛从入门到国奖》算法基础:动态规划-路径dp
数据结构·c++·算法·动态规划
算法鑫探19 小时前
C语言实战:学生成绩统计与分析
c语言·数据结构·算法·新人首发
_日拱一卒19 小时前
LeetCode:最小覆盖字串
java·数据结构·算法·leetcode·职场和发展
郝学胜-神的一滴19 小时前
Qt6 + OpenGL 3.3 渲染环境搭建全指南:从空白窗口到专属渲染画布的优雅实现
数据结构·c++·线性代数·算法·系统架构·图形渲染
小肥米20 小时前
分块查找ASL公式推导,为什么是两个ASL之和
数据结构·算法