1. 平衡树基础与FHQ-Treap的诞生背景
在计算机科学领域,平衡二叉搜索树(Balanced Binary Search Tree)一直是处理动态数据集的核心数据结构。传统AVL树和红黑树通过严格的旋转操作维持平衡,而Treap(Tree + Heap)则另辟蹊径,通过为每个节点随机分配优先级(priority),结合二叉搜索树的性质和堆的性质来实现概率平衡。
FHQ-Treap由范浩强(Fan Haoqiang)在2012年提出,其革命性在于完全摒弃了旋转操作。这种无旋特性使得代码实现异常简洁——核心操作仅需两个函数:split(分裂)和merge(合并)。实测表明,FHQ-Treap的代码量可比传统Treap减少40%,而时间复杂度仍保持期望O(log n)。
关键突破:split和merge操作的时间复杂度均为O(h),其中h为树高。由于Treap的随机优先级特性,h的期望值为O(log n),这使得FHQ-Treap在绝大多数场景下表现优异。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. FHQ-Treap的核心原理解析
2.1 节点结构设计
FHQ-Treap的每个节点包含四个基本字段:
cpp复制struct Node {
int val; // 节点值(BST性质)
int pri; // 随机优先级(堆性质)
int size; // 子树大小(支持排名操作)
Node *l, *r; // 左右子节点指针
};
其中pri的随机性至关重要——通过系统随机数生成器(如C++的mt19937)为每个新节点分配优先级,确保树高期望平衡。
2.2 分裂操作(split)的数学本质
split操作接受一个参数x,将树划分为两个子树T1和T2,满足:
- T1包含所有val ≤ x的节点
- T2包含所有val > x的节点
递归实现的关键在于比较当前节点val与x的关系:
cpp复制void split(Node *t, int x, Node *&L, Node *&R) {
if (!t) { L = R = nullptr; return; }
if (t->val <= x) {
L = t;
