1. 伸展树介绍
伸展树是一种自调整二叉搜索树,由 John Edward Hopcroft 和 Robert Endre Tarjan 于 1985 年发明。与 AVL 树不同,伸展树不追求严格的平衡,而是通过'伸展'操作将最近访问的节点移至根节点,利用局部性原理优化频繁访问的场景。
核心思想
- 单一旋转:将经常访问的结点上移。
- 移动到根部:假设结点将被再次访问,反复旋转直至其位于根节点。
旋转类型
每次访问(搜索、插入或删除)一个结点时,执行'展开'过程,包含三种旋转:
- 单旋转:被访问结点的父结点是根结点时执行。
- 一字形旋转:同构形状(如左 -左或右 -右)时执行双旋转。
- 之字形旋转:异构形状(如左 -右或右 -左)时执行双旋转。
算法描述
void splaying(Node* g, Node* p, Node* s) {
// g 是 p 的父结点,p 是 s 的父结点。算法将 s 移到根结点位置
while (s != root) {
if (p == root) {
rotateSingle(s); // 单旋转
} else if (isSameDirection(p, g)) {
rotateZigzag(s); // 一字形双旋转
} else {
rotateZigZag(s); // 之字形双旋转
}
}
}
时间复杂度
对于 n 个结点的树执行 m 次操作,总时间复杂度为 O(m log n),均摊时间复杂度为 O(log n)。适合缓存、热点数据查询等场景。
2. 红黑树介绍
2.1 概念
红黑树是一棵二叉搜索树,每个结点增加颜色属性(红色或黑色)。通过对路径上结点颜色的约束,确保没有一条路径比其他路径长出两倍,从而实现近似平衡。
2.2 性质
- 根结点和所有外部结点(NIL)的颜色是黑色。
- 从根到外部结点的途中没有连续两个红色结点。
- 所有从根到外部结点的路径上都有相同数目的黑色结点。
2.3 最长路径限制
最短路径为全黑路径(长度 bh),最长路径为一黑一红间隔(长度 2bh)。因此任意路径长度满足 bh <= h <= 2bh。
2.4 效率
红黑树高度最大为 2 log₂(n+1),增删查改最坏时间复杂度为 O(log n)。相比 AVL 树,红黑树在插入时旋转次数更少,维护成本更低,常用于 C++ STL 容器。
3. 红黑树的实现
3.1 结构定义
{ RED, BLACK };
< , >
{
pair<K, V> _kv;
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
Colour _col;
( pair<K, V>& kv)
:_kv(kv), _left(), _right(), _parent(), _col(RED) {}
};


