红黑树在 C++ 标准库中是 std::map、std::set 等关联容器的底层实现(GCC libstdc++ 和 Clang libc++ 均采用红黑树),它是一种自平衡二叉搜索树,通过节点着色(红/黑)和局部旋转+变色操作,在 O(log n) 时间内保证插入、删除、查找的最坏性能。
理解实现前必须牢记五条不变性(即“红黑性质”):
插入新节点默认为红色(避免直接破坏性质5),但可能违反性质4(出现红-红父子)。此时需根据父节点、叔节点颜色及位置关系分情况处理:
三种情况均能在至多两次旋转 + 若干变色后恢复红黑性质。实际编码中常将“内侧→外侧”合并为统一的旋转预处理步骤。
典型节点结构包含:key、value(对 map)、color(bool 或 enum)、left、right、parent 指针。STL 实现中常用 带父指针的三叉链表,便于回溯修复;部分精简实现会省略 parent,改用栈记录路径(但增加常数开销)。
为避免频繁 new/delete,现代实现(如 libstdc++)使用 std::allocator + 内存池管理节点,构造/析构由容器控制,不暴露裸指针给用户。
std::map 是红黑树的键值对映射,按 K 排序;std::set 是仅存 key 的集合;std::multimap 和 std::multiset 允许重复 key,插入时不检查等价性,仅依赖 lower_bound 定位插入位置。
所有操作时间复杂度均为 O(log n),迭代器稳定(插入删除不使原有迭代器失效,除非指向被删节点),遍历结果严格升序(基于 operator 或自定义比较器)。
不复杂但容易忽略:红黑树不是唯一选择——C++20 后部分场景可用 std::unordered_map(哈希表,平均 O(1))替代,但牺牲有序性和最坏 O(n) 查找;而红黑树提供确定性对数级性能和天然有序
遍历能力,这是关联容器设计的根本权衡。