[平衡树] 平衡树学习笔记

好久不见!
就差这个坑就补齐了!
估计高三也不会太更博客了,不知道是不是NOIP前的最后一篇?
在博客园的新博客欢迎关注!
发现自己平衡树学了跟没学一样,退役了简单学了一发……
平衡树有很多,比如AVL树,红黑树(RBTree)什么的,AVL被魔改成SBT?RBTree是系统中的平衡树。但是不常用不介绍了。
平衡树的本质是一棵二叉搜索树(Binary Search Tree,即BST),规定一个二叉树,其左儿子的值都小于它,其右儿子的值都大于它,也就是说把二叉搜索树按中序遍历即可对这些数进行排序。但是这个二叉搜索树不是唯一的。
我们可以用BST解决一些维护集合问题,比如插入一个数,查询某数排名(第几小)和查询第 k 大数。直接按着定义模拟,把BST搜一遍即可完成操作。
可是这种操作很爆炸,当按照从小到大的顺序插入数据的时候复杂度会很大(此时BST为一条链),而且删除操作很困难。
那么就需要一些操作维护这棵BST了。
我们发现,有两个操作:左旋和右旋可以在不破坏BST性质的情况下维护这棵BST不会退化成链的形式。
下面给出一棵BST的一部分
BST
右旋的意思即为:对于 k 节点,把父亲节点 x 作为自己的右儿子,自己的右儿子作为旋转后 x 的左儿子。
分步的操作如下:
Rturn1->Rturn2
因为 lc<k<rc<x<RC ,旋转后仍符合。
那么左旋就很好理解了:对于 k 节点,把父亲节点 x 作为自己的左儿子,自己的左儿子作为旋转后 x 的右儿子。
Lturn1->Lturn2
这样旋转有什么用呢?
于是就有这几种维护方式了!

1、Splay

Splay可以说是一种经典的维护方式了,通过维护 x -父亲-祖父的关系实现平衡,也就是判断这三个点是否在一条直线上实现平衡。
记录操作 Splay(x) 为把 x 节点转到根上。这样很容易就可以快速查找了。
那么如何旋转呢?
于是我们开始了大段的讨论:(其实就三种……)
1、 x 的父亲就是根……
转一次就行了……
2、 x -父亲-祖父在一条直线上:
这种情况如图:
Splay1
现在 f x 的左儿子, g f 的左儿子(右儿子同理,只不过操作相反),那么我们将 g 右旋,再将 f 右旋即可(如果右儿子即为左旋),这个是Zig-Zig(Zag-Zag)操作。
如图所示……
Splay2->Splay3
这样 x 就是根了!
3、 x -父亲-祖父不在一条直线上:
就是拧着的呗……
Splay4
现在 f g 的右儿子, x f 的左儿子(反着的同理),我们反向操作,对 f 右旋,再对 g 左旋即可把 x 转到根上。这个是Zig-Zag(Zag-Zig)操作。
如图所示……
Splay5->Splay6
于是我们可以把任意一个节点都转到根上了!
那么复杂度呢……
根据势能分析,可知 n 个点, m 次操作的Splay树的时间复杂度为 O((n+m)log2n)
这里的势能可以理解为物理学势能,网上证明应该很多吧……这里不贴了……
Splay应用广泛,可以支持动态序列操作(如普通的平衡树),还可以支持区间变化的操作,比如区间反转,区间移动等。
如何在Splay上提取区间呢?
记需要提取 [l,r] ,那么把 l1 提到根,将 r+1 提到根的右子树,那么根的右子树的左子树(即 r+1 的左子树)即为 [l,r] 区间的所有元素,就可以根节点打标记来维护了。
但是当 l=1 时没有 0 元素,当 r=n 时没有 n+1 元素,这样就需要手动添加 0 n+1 元素了。
Splay还可以用在Link-Cut Tree上(即动态树),就可以维护森林中每棵树的形态了。这玩意很玄学就不补板子了……
Splay在遇到有序数据的时候还会被卡……

2、Treap

Treap是个很玄学的数据结构,它是BST和Heap的合体版本。
堆是个二叉树,其每个节点的优先级比儿子们的优先级都要小,这就是priority_queue的实现方式。
因为BST是因为一些有序数据使得其退化,然而随机数据可以认为是无序的。那么把随机数当做Heap的优先级维护Tree就可以达到平衡BST的作用。所以,我们利用左旋和右旋操作保持Heap的性质,即可达到BST的平衡。
Treap的树高期望是 O(log2n) 的,所以它的复杂度是期望 O(log2n) 的。
Treap还有无旋维护的,是利用把树分成两块再合并的操作维护。
Treap还可以演变为替罪羊树,主要思想是暴力重构……是一种重量平衡树。
可以用Windows卡Treap(Windows下的rand范围比较小,再乘一个rand就可以防卡了……)

3、SBT

SBT是2006年在冬令营上首次出现的,可是被诸神犇喷不知道为什么……据说是换了一种方式维护AVL。
主要是用Maintain操作维护平衡,而且这个Maintain操作是均摊 O(1) 的非常快(据说比AVL,Treap,Splay快很多)。
知乎上陈启峰本人已经给出了资料包,可以参考。
貌似SBT只能刷裸题+刷时间榜……
下面是喜闻乐见的板子时间……
Splay
Treap
SBT

猜你喜欢

转载自blog.csdn.net/HeRaNO/article/details/76168035
今日推荐