容器 map 和 set 的底层实现均依赖于红黑树。本文深入探讨如何利用红黑树封装这两种标准容器,剖析其设计精妙之处与底层逻辑。
1. map/set 设计的巧妙之处
map 存储 key/value 对,set 仅存储 key。面对两种不同的参数类型,如何复用同一套红黑树结构?
直观方案是维护两棵独立的红黑树,但这会导致代码复用率极低且维护成本高昂。工程实践中,我们采用**键提取器(仿函数)**来统一处理:通过一个泛型接口提取 key,用同一颗红黑树同时支撑 map 和 set。 C++ 中的仿函数比 C 语言的函数指针更加灵活且类型安全。

接下来,我们基于红黑树进行 map 和 set 的具体封装。
2. map 和 set 的实现
2.1 基本框架与模板通用化
map 是 key-value 结构,set 是 key 结构。为了共用底层红黑树,我们需要将参数通用化:
// 原红黑树可能定义为 K, V
// 现在统一为 T,T 可以是 pair<K,V> 或 K
template <typename T>
class RBTree {
// ...
};
根据数据类型不同,分别编写对应的仿函数来控制底层获取 Key 的行为。


上层调用时传入仿函数对象,下层红黑树需新增一个模板参数接收该仿函数类型。

2.2 Insert 操作
原本的红黑树插入 KV 结构,现在只需传入 data。data 的类型可能是 pair<K,V> 也可能是 Key。创建仿函数对象后,即可提取出用于比较的 Key。

































