平衡树(Splay) 服务:第一弹——旋转的艺术
0.前言
本蒟蒻前不久刚学SPLAY,有了一点心得,想要巩固下来。同时也觉得网上的神犇们实在太强了,有的内容并不能很好的让我这样的蒟蒻理解,因此便有了我这篇RBQ级服务的博客。我的splay是看自有风月马前卒学的,因此部分代码可能有些相似。自有风月马前卒是一位高产的神犇,强烈推荐大家看他的博客
1.引入:何为平衡树
平衡树,大家一定都听说过(毕竟没听说过也不会来找Splay博客),那么,平衡树到底是怎么回事呢?就让小编一起带大家来看看吧
平衡树是一种 二叉搜索树(BST) ,它拥有二叉搜索树的重要性质:对于BST的一个节点,它的左子树都比它小,右子树都比它大。BST因为有了这个性质,就可以以O(mh)O(mh)O(mh)的复杂度方便的实现插入,删除,查询前后驱,排名,k小值等功能。没错,正是平衡树常用的功能。好的,BST取代了平衡树,本篇完————
怎么可能???
BST的性质可以理解为,它是一个中序遍历为有序数列的二叉树,而我们知道,对于一棵树,只知道中序遍历是无法确定它的形态的,因此,插入顺序的不同会导致BST形态的不同。在极端情况下,它会退化成一条链,这时使用BST的复杂度就退化成了O(mn)O(mn)O(mn)。(ps:vector在一般情况下也能以远低于O(mn)O(mn)O(mn)的复杂度完成以上操作)。
那该怎么办?用vector(
为了拯救Oier和BST,平衡树出现了。考虑到BST之所以会退化,是因为它在可能会变得非常“窄长”,于是,我们可以使用人为方式让BST保持宽宽扁扁的“好身材”,来保证复杂度为O(mlogn)O(m\log n)O(mlogn)这就是平衡树的由来。
平衡树可以分成不同的种类:
通过旋转操作实现平衡的:有旋Treap,Splay(伸展树),WBLT,AVL Tree,(左偏)红黑树
通过分裂与合并操作实现平衡的:FHQ Treap(无旋Treap)
通过暴力拍扁实现平衡的(害怕 :替罪羊树
由于本蒟蒻实在太蒻,只会Splay,因此就只跟大家讲Splay了
2.平衡?先得有树!
在开始splay之前,我们首先要准备一颗二叉树
如下:
#define maxn 100005
struct splayTree
{
int val, ch[