【数据结构】平衡树引入
数据结构-平衡树
前置知识
- 二叉树
- 二叉树的中序遍历
问题
维护一个数据结构,支持插入元素、删除元素、查询元素的排名、查询排名对应的元素、查询元素的前驱、查询元素的后继等。
BST(二叉搜索树)
作为一个基本无效(很容易卡掉)的数据结构,将其放在这里讲可能更为合适。。。
BST 的思想,来自于二叉树的 DFS 序。
设想一下,若一个二叉树的中序遍历正好递增,也就是说,始终有
左儿子
≤
根
≤
右儿子
左儿子\le根\le右儿子
左儿子≤根≤右儿子,那么不就可以达到
O
(
树高
)
O(\text{树高})
O(树高) 的复杂度了吗?
可能不是这样。设想一组数据,令插入的第
i
i
i 个节点为
i
i
i,BST 便会退化为
O
(
n
2
)
O(n^2)
O(n2),长成一条链。
思路
为了弥补 BST 的各种劣势,聪明的 OIers 发明了平衡树。
对于上面卡掉 BST 的样例,平衡树的一种画法长这样:
可以看出来,平衡树是非常平衡的。
平衡树的重要处理就是维护其平衡性。
接下来介绍一下用来维护平衡树的平衡性质的两种操作——左旋(
Zag
\text{Zag}
Zag)和右旋(
Zig
\text{Zig}
Zig)
-
Zag
\text{Zag}
Zag:
如果有一个失衡子树长这样:
需要将节点 q \text q q 旋转至节点 p \text p p,我们可以这样:
注意到,其中序遍历是不变的。 -
Zig
\text{Zig}
Zig:
如果有一个失衡子树长这样:
需要将节点 q \text q q 旋转至节点 p \text p p,我们可以这样:
注意到,其中序遍历是不变的。
由于不同的平衡树对失衡子树的处理方式是不同的,所以这里不再赘述,可以去下方的文章学习。
数据结构参数
- 单次修改时间复杂度: Θ ( log ? n ) \Theta(\log n) Θ(logn)
- 单次查询时间复杂度: Θ ( log ? n ) \Theta(\log n) Θ(logn)
- 空间复杂度: Θ ( n ) \Theta(n) Θ(n)
代码
这里放一下 Zag \text{Zag} Zag 和 Zig \text{Zig} Zig
void Zag(int &p){//左旋
int q=t[p].r;
t[p].r=t[q].l;
t[q].l=p;p=q;
Pushup(t[p].l);Pushup(p);
}
void Zig(int &p){//右旋
int q=t[p].l;
t[p].l=t[q].r;
t[q].r=p;p=q;
Pushup(t[p].r);Pushup(p);
}
接下来是三种基本的平衡树:
- AVL
- Treap
- Splay
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!