平衡树是一个很神奇的数据结构
noip前,学了其两种实现方式,Splay和Treap,非常实用(虽然码量有点。。)
每个平衡树都是二叉查找树,保证(左孩子 leq 自己 leq 右孩子)
因此,平衡树的中序遍历就是插入节点的有序序列(理解一下)
平衡树支持插入,删除,以及各种查询,以下面为例
(color{#0066ff}{题目描述})
您需要写一种数据结构,来维护一些数,其中需要提供以下操作:
插入数x
删除x数x(若有多个相同的数,只删除一个)
查询数x的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,输出最小的排名)
查询排名为x的数
求x的前驱(前驱定义为小于x,且最大的数)
求x的后继(后继定义为大于x,且最小的数)
(color{#0066ff}{输入格式})
第一行为n,表示操作的个数,下面nn行每行有两个数opt和x,opt表示操作的序号(1leq opt leq 6)
(color{#0066ff}{输出格式})
对于操作3,4,5,6每行输出一个数,表示对应答案
(color{#0066ff}{输入样例})
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
(color{#0066ff}{输出样例})
106465
84185
492737
这就是洛谷P3369普通平衡树板子
总的来说,平衡树的实现方式有6种:SBT,Splay,Treap,AVL,RBT,替罪羊
其实还有一个是普通的二叉查找树:BST,由于太过辣鸡。。。很容易被卡,此处不提
对于AVL,实用性比较低,比如代码长度,精简度不如SBT,速度倒是差不多,对大数据的处理不如RBT,对可持久化的支持又不如FAQ,灵活性又没有Splay高,还不能像替罪羊树那样支持树套树,此处也不提了
那么,这些平衡树根BST有啥区别呢,为什么平衡树要比BST快好多好多呢?
试想一下,当插入的节点使树变成一条链时,每次查找最坏岂不是(O(n))? 显然TLE。。。
这些平衡树,各有各的长处,每一个都有骚操作使自己平衡,防止复杂度过高
大部分平衡树要依靠旋转(除了Treap,替罪羊)
这里,把旋转提一下
