非旋转Treap
非旋转Treap
通过节点的优先级来维护树的平衡, 下面是普通非旋转Treap (弱平衡,
性质
- Treap是笛卡尔树的一种,只是 节点优先级是随机的
- $Tree+Heap$: 二叉搜索树+堆的性质
- 2个核心操作 分裂+合并
分裂 split
按照 节点权值分裂或者值的排名分裂
$split_val$
将一颗
treap分裂成2个treap,第一个treap所有节点的权值$\le key$ , 第二个treap所有节点的权值$\gt key$
判断节点权值$val[index]$ 是否 $\le key$,
- 若$val[index]\le key$,则第一个$treap$就是 $index$及其左子树, 但右子树可能还有节点权值$\le key$,所以再去$index$的右子树去分裂
- 若$val[index] \gt key$,则第二个$treap$就是$index$及其右子树.但左子树可能还有节点权值$\gt key$ ,所以再去$index$左子树去分裂```c
// oi-wiki 上的指针版
pair<node *, node *> split(node *u, int key) {
if (u == nullptr) {
return make_pair(nullptr, nullptr);
}
if (key < u->key) {
pair<node *, node *> o = split(u->lch, key);
u->lch = o.second;
return make_pair(o.first, u);
} else {
pair<node *, node *> o = split(u->rch, key);
u->rch = o.first;
return make_pair(u, o.second);
}
}
1 | |
其他操作 (都是基于分裂和合并)
- 建树(
我现在只会一个一个插入) - $insert(val) = split_val + new_node + merge$
- $delete(val) = split_val + split_kth + merge$
- $rank(val) = split_val + merge$
- $kth(k) = split_kth*2 + merge$
- $pre(val) = split_val + split_kth + merge$
- $nxt(val) = split_val + split_kth +merge$
1 | |
%%%% 大佬非旋Treap
杂: 1天+1早上