c++红黑树

一、为什么需要红黑树?

在编程中,我们经常需要一个动态维护有序数据的结构。比如:

  • std::mapstd::set 的底层实现
  • Linux内核的进程调度器
  • 数据库的索引结构

如果使用普通的二叉搜索树(BST),极端情况下会退化成链表(如插入有序数据),导致查找效率从 O(log n) 降为 O(n)。为了解决这个问题,红黑树(Red-Black Tree)应运而生。

二、红黑树的核心思想

红黑树是一种自平衡的二叉搜索树,它通过以下规则实现近似平衡:

红黑树的5大规则

  1. 每个节点非红即黑
  2. 根节点必须是黑色
  3. 红色节点的子节点必须是黑色(不能出现连续的红色)
  4. 从任意节点到其空子节点的路径上,黑色节点的数量必须相同
  5. 每个叶子节点(空节点)是黑色

为什么这些规则能保证效率?

  • 最长路径 ≤ 2 × 最短路径
    例如,如果最短路径有 k 个节点,最长路径最多有 2k 个节点。这确保了红黑树的高度始终在 O(log n) 范围内。

三、红黑树的插入操作详解

插入新节点时,红黑树需要通过变色 + 旋转维持平衡。以下是典型场景:

情况1:父节点是黑色

  • 直接插入即可,无需调整。

情况2:父节点是红色

此时需要根据叔叔节点的颜色进行处理:

子情况1:叔叔是红色
  • 操作:父节点、叔节点变黑,祖父节点变红,并继续向上处理。

    祖父(黑) → 父(红) → 当前(红)
    叔(红)

子情况2:叔叔是黑色或不存在

需要通过旋转调整:

  • LL型(当前节点在左子树的左子树):右单旋 + 变色
  • RR型(当前节点在右子树的右子树):左单旋 + 变色
  • LR型(当前节点在左子树的右子树):左右双旋 + 变色
  • RL型(当前节点在右子树的左子树):右左双旋 + 变色

四、红黑树的代码实现

cpp 复制代码
enum Color { RED, BLACK };

template <typename K, typename V>
struct RBTreeNode {
    RBTreeNode* left;
    RBTreeNode* right;
    RBTreeNode* parent;
    std::pair<K, V> kv;
    Color color;

    RBTreeNode(const K& key, const V& value)
        : left(nullptr), right(nullptr), parent(nullptr), kv(key, value), color(RED) {}
};

template <typename K, typename V>
class RBTree {
public:
    void insert(const K& key, const V& value) {
        // 二叉搜索树插入逻辑
        // ...
        // 插入后调整平衡
        fixInsert(newNode);
    }

private:
    void fixInsert(RBTreeNode<K, V>* node) {
        while (node->parent && node->parent->color == RED) {
            // 处理四种情况
            // ...
        }
        root->color = BLACK;
    }

    RBTreeNode<K, V>* root;
};

五、红黑树的应用场景

1. C++ STL容器

  • std::mapstd::set 默认使用红黑树实现(C++11)。
  • 插入/删除操作时间复杂度为 O(log n)

2. Linux内核

  • 完全公平调度器(CFS) 使用红黑树管理进程队列。
  • 快速找到下一个要运行的进程。

3. 数据库索引

  • MySQL 的 InnoDB 引擎使用 B+ 树(红黑树的扩展)作为索引结构。
相关推荐
kaikaile19959 分钟前
数字全息图处理系统(C# 实现)
开发语言·c#
秋91 小时前
Go语言(Golang)开发工程师全景解析:岗位职责·语言优势与使用场景·各城市薪资·发展前景·高考志愿填报(2026版)
开发语言·golang·高考
huangdong_2 小时前
1688商品图片采集技术解析:登录态处理与SKU图自动分类
开发语言
搬砖魁首2 小时前
基础能力系列 - 多线程2 - 条件变量
c++·rust·条件变量·原子类型·线程同步互斥
chase_my_dream2 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
牛油果子哥q3 小时前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
Cloud_Shy6183 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
天佑木枫3 小时前
15天Python入门系列 · 序
开发语言·python
宋拾壹4 小时前
同时添加多个类目
android·开发语言·javascript
凡人叶枫5 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发