数据结构科普-红黑树

红黑树

红黑树由 鲁道夫·贝尔 (Rudolf Bayer)在1972年提出,最初叫"对称二叉B树 "(Symmetric Binary B-Trees)。

后来在1978年,莱昂纳德·吉布斯 (Leonard Guibas)和 罗伯特·塞奇威克 (Robert Sedgewick)在研究中引入了"颜色"的概念来描述节点状态,并正式命名为"Red-Black Tree"。

名字的由来与"奇葩"之处

红黑树的命名听起来很酷,甚至有点像某种神秘组织或武侠门派,比如"红莲教""黑风寨"......但实际上,它的名字毫无浪漫色彩,也和红与黑的哲学无关

他们选择"红"和"黑",并不是因为:

  • 红色代表危险、黑色代表安全,
  • 或者红是革命、黑是镇压,
  • 也不是像围棋那样象征阴阳...... 它的名字来源其实非常"工程"、非常"现实":

红黑只是用来标记节点的两种颜色,选"红"和"黑"仅仅是因为------当年所用的打印设备能很好地区分这两种颜色。 但正是这种"不讲究"的命名,反而体现了计算机科学中一种典型的风格:功能优先,名字随意,能用就行。

所以,"红黑"本质上就像"A状态"和"B状态",换成"绿黄树""上下树""01树"也未尝不可,只是"红黑"这个叫法被历史保留了下来。


这也算是技术史上的一个有趣花絮,让红黑树不仅是一棵平衡树,还带点"冷幽默"的色彩。

定义

红黑树(Red-Black Tree)是一种自平衡的二叉搜索树 (Self-balancing Binary Search Tree),它在普通二叉搜索树的基础上,通过为每个节点添加一个"颜色"属性(红色或黑色),并遵守一组特定的规则,来确保树的整体高度始终保持在对数级别,从而保证查找、插入、删除操作的时间复杂度为 O(log n)


五大性质(规则)

每个节点必须满足以下五条性质:

  1. 每个节点是红色或黑色
  2. 根节点是黑色
  3. 每个叶子节点(NIL 节点,即空指针)是黑色
    (这些是逻辑上的叶子,实际实现中常以 null 或哨兵节点表示)
  4. 红色节点的子节点必须是黑色(即不能有两个连续的红色节点,父子不能同红)。
  5. 从任一节点到其每个叶子的所有路径上,包含相同数目的黑色节点(称为"黑高"一致)。

这五条规则共同作用,使得红黑树在最坏情况下也能保持近似平衡。

核心原理

  1. 平衡机制

    不像 AVL 树那样严格保持左右子树高度差不超过 1,红黑树是弱平衡 的。

    它通过颜色标记和旋转操作,在插入和删除后进行局部调整,防止树退化成链表。

  2. 插入与删除的调整策略

    • 插入新节点默认为红色
      因为插入黑色会破坏"黑高"规则(第5条),而插入红色只可能违反"不能连续红"(第4条),更容易修复。
    • 修复操作包括
      • 变色(recolor)
      • 左旋(left rotate)
      • 右旋(right rotate)
    • 删除后也可能需要调整
      删除黑色节点会破坏黑高,需要通过兄弟节点的调整(如借节点、合并)来修复。
  3. 旋转操作

    • 左旋:将右子树"提上来",原节点成为其左子节点。
    • 右旋 :将左子树"提上来",原节点成为其右子节点。
      旋转不改变中序遍历结果(仍保持二叉搜索树性质),但能改变结构以恢复平衡。

红黑树的特点

特点 说明
时间复杂度 查找、插入、删除均为 O(log n),最坏情况性能稳定。
平衡性 弱平衡,最长路径不超过最短路径的两倍。
效率 插入和删除的调整次数通常较少,比 AVL 树更"宽松",适合频繁修改的场景。
实现复杂度 比普通二叉搜索树复杂,但比 AVL 树稍简单(调整次数少)。

实际实现中的关键设计

  1. 节点结构通常包含三个指针

    • left:左孩子
    • right:右孩子
    • parent:父节点
  2. parent 指针的作用

    • 可以快速访问父节点、兄弟节点、叔节点、祖父节点。
    • 在插入/删除修复过程中,无需从根节点重新搜索路径。
    • 实现旋转、变色等操作更高效。
  3. 为什么加 parent 指针?

    • 虽然理论上可以不用,但会极大增加查找父节点的成本。
    • 实际工程中(如 C++ STL 的 map/set、Linux 内核的进程调度、Java 的 TreeMap)都使用了 parent 指针。
    • 是典型的 空间换时间 设计。

红黑树 vs 其他平衡树

对比项 红黑 树 AVL 树 普通 BST
平衡严格性 弱平衡 严格平衡 不平衡
插入/删除性能 更快(调整少) 较慢(可能多次旋转) 快(不调整)
查找性能 稍慢(树稍高) 更快(树更矮) 最坏 O(n)
适用场景 频繁插入删除 频繁查找 简单场景
实现复杂度 中等 较高 简单

应用场景

  • C++ STL 中的 std::mapstd::set
  • Java 中的 TreeMapTreeSet
  • Linux 内核中的 CFS(完全公平调度器)使用红黑树管理进程
  • 数据库索引结构(某些实现)
  • 网络路由表、事件调度器等需要高效动态维护有序数据的系统

总结一句话:

红黑树是一种高效、实用的自平衡二叉搜索树,通过颜色规则和旋转操作维持近似平衡,实际实现中通常包含 parent 指针以支持快速访问父节点和兄弟节点,是"空间换时间"的经典体现,广泛应用于现代系统和库中。

相关推荐
.ZGR.4 小时前
蓝桥杯高校新生编程赛第一场题解——Java
java·算法·蓝桥杯
每天进步一点点dlb5 小时前
JVM中的垃圾回收算法和垃圾回收器
jvm·算法
我爱鸢尾花5 小时前
CNN基础理论讲解及Python代码复现
人工智能·python·深度学习·神经网络·算法·机器学习·cnn
大数据张老师5 小时前
数据结构——二叉搜索树
数据结构·算法·二叉搜索树·查找·关键路径
攻城狮CSU5 小时前
类型转换汇总 之C#
java·算法·c#
小老鼠不吃猫6 小时前
C++ STL <algorithm>中泛型算法:查找、排序、修改、统计、生成
c++·算法·排序算法
白杆杆红伞伞6 小时前
01_svm_二分类
算法·支持向量机·分类
isyoungboy6 小时前
使用SVM构建光照鲁棒的颜色分类器:从特征提取到SVM
算法·机器学习·支持向量机
极客数模6 小时前
2025年MathorCup 大数据竞赛明日开赛,注意事项!论文提交规范、模板、承诺书正确使用!2025年第六届MathorCup数学应用挑战赛——大数据竞赛
大数据·python·算法·matlab·图论·比赛推荐