C++红黑树封装map和set核心技术解析
·
C++红黑树封装map和set详解
一、核心设计思路
红黑树作为底层数据结构,通过模板特化实现map和set的差异化封装:
template <typename Key, typename Value>
class RBTreeMap { /* 键值对存储 */ };
template <typename Key>
class RBTreeSet { /* 单键存储 */ };
二、节点结构设计
- 统一基础节点:
enum Color { RED, BLACK };
template <typename T>
struct RBTreeNode {
T data;
Color color;
RBTreeNode* left;
RBTreeNode* right;
RBTreeNode* parent;
};
- 特化节点类型:
// Set节点
template <typename Key>
struct SetNode : RBTreeNode<Key> { /* 仅存储Key */ };
// Map节点
template <typename Key, typename Value>
struct MapNode : RBTreeNode<std::pair<Key, Value>> {
Value& get_value() { return data.second; }
};
三、核心操作实现
-
插入修复(双红修正):
- 情况1:叔节点为红
void fixInsertCase1(Node* node) { uncle->color = BLACK; parent->color = BLACK; grandparent->color = RED; fixInsert(grandparent); }- 情况2/3:叔节点为黑(LL/RR型)
void fixInsertCase2(Node* node) { if (node == parent->left) { rotateRight(grandparent); } else { rotateLeft(grandparent); } swapColor(parent, grandparent); } -
左旋操作:
void rotateLeft(Node* x) {
Node* y = x->right;
x->right = y->left;
if (y->left) y->left->parent = x;
y->parent = x->parent;
if (!x->parent) root = y;
else if (x == x->parent->left) x->parent->left = y;
else x->parent->right = y;
y->left = x;
x->parent = y;
}
四、容器接口封装
- set接口实现:
template <typename Key>
class RedBlackSet {
public:
void insert(const Key& key) {
auto node = new SetNode<Key>(key);
tree.insert(node);
}
bool contains(const Key& key) const {
return tree.search(key) != nullptr;
}
private:
RBTree<Key> tree;
};
- map接口实现:
template <typename Key, typename Value>
class RedBlackMap {
public:
Value& operator[](const Key& key) {
auto node = tree.search(key);
if (!node) {
node = new MapNode<Key, Value>(key, Value());
tree.insert(node);
}
return node->get_value();
}
private:
RBTree<std::pair<Key, Value>> tree;
};
五、迭代器设计
template <typename Node>
class TreeIterator {
public:
TreeIterator& operator++() {
if (current->right) {
current = minNode(current->right);
} else {
while (current->parent && current == current->parent->right) {
current = current->parent;
}
current = current->parent;
}
return *this;
}
private:
Node* minNode(Node* node) const {
while (node->left) node = node->left;
return node;
}
Node* current;
};
六、性能分析
- 时间复杂度:
- 插入/删除:$O(\log n)$
- 查找:$O(\log n)$
- 空间复杂度:$O(n)$
七、关键技巧总结
- 模板特化:通过
std::conditional选择节点类型using NodeType = std::conditional_t<is_map, MapNode<Key, Value>, SetNode<Key>>; - 颜色标记:使用枚举确保红黑树性质
- 迭代器失效:插入/删除操作仅影响局部指针
- 内存管理:使用RAII技术自动释放节点内存
完整实现需处理边界条件(如空树、根节点变色等),建议结合《算法导论》红黑树章节实现删除操作的修正逻辑。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)