关于平衡树的一些总结
Posted wfj_2048
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于平衡树的一些总结相关的知识,希望对你有一定的参考价值。
平衡树是个大专题啊qwq。。最近也学了一些很有用的平衡树,写个总结吧。。
一.splay
学的第一个平衡树,复习一下。。
splay是一个功能很强大的二叉搜索树。其实讲道理splay并不算平衡树吧,因为它并没有任何关于树高的限制。splay的原理就是,每次插入或查询一个结点,就把它旋转到根结点,这样与搜索引擎的原理类似,查询次数较多的结点就能更靠近根。splay并不能保证每次操作严格复杂度都是O(logn),但是每次操作的均摊复杂度确实可以是O(log)。。然而我也不知道为什么。。不过splay好像有可能会被卡来着。。但是splay在序列上的操作可以说几乎完美,因为它可以任意旋转。splay的编程复杂度也是很小的。
splay的核心在于splay操作,即调用splay(x,f),就是把x旋转到f的儿子上(特别地,如果把x旋到根那么f=0)。splay的旋转分为3种——zig,zig-zig,zig-zag。zig操作,就是当x的父亲已经是f的儿子时,直接旋转x。zig-zig,当x与x的父亲位于同一侧时(就是说,x是x的父亲的左儿子,x的父亲是x的父亲的父亲的左儿子,反之也成立)。先旋转x的父亲,再旋转x。zig-zag,当x与x的父亲位于不同侧时,直接旋转两次x。这里的旋转,就是指,如果x是它父亲的左儿子,那么就把他右旋,否则左旋。感觉上个图会更容易理解些。。
然后就是上代码了。。
1 il void rotate(RG int x){ 2 RG int y=fa[x],z=fa[y],k=ch[y][0]==x; 3 ch[z][ch[z][1]==y]=x,fa[x]=z; 4 ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y; 5 ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return; 6 } 7 8 il void splay(RG int x,RG int goal){ 9 RG int top=0; st[++top]=x; 10 for (RG int i=x;fa[i]!=goal;i=fa[i]) st[++top]=fa[i]; 11 for (RG int i=top;i;--i) if (lazy[st[i]]) pushdown(st[i]); 12 while (fa[x]!=goal){ 13 RG int y=fa[x],z=fa[y]; 14 if (fa[y]!=goal){ 15 ((ch[z][0]==y)^(ch[y][0]==x)) ? rotate(x) : rotate(y); 16 } 17 rotate(x); 18 } 19 if (!goal) rt=x; return; 20 }
splay还是很好写的吧,还能对一个序列进行分裂和合并这种神奇的操作qwq。。
二.替罪羊树
替罪羊树也是一种很好写的平衡树qwq。。替罪羊树的核心思想就是重构。即当一棵子树的平衡被破坏,那么就把这棵树拍平,也就是树高为O(logn)的完美二叉树形态。这样看似复杂度很高,实则不然。可以证明,替罪羊树每次重构的复杂度都是均摊O(logn)的。反正我也不会证明,证明还要用物理学知识。。
---------------------------------------------------------------------------------------------------------------------------------------------------
具体是这样操作的:我们设定一个参数α,满足α∈[0.5,1)。(其实如果你设定α为0.5那就会T飞~)
α高度平衡:树高h≤log1an
α大小平衡:对于一个结点p满足max(sizelp,sizerp)≤αsizep
如果每个结点均满足α大小平衡,假设最深的点为dd,那么有1≤nαdepd
那么depd≤logα1n=log1αndepd≤logα1n=log1αn,即满足α高度平衡。
插入和普通BST类似,只需要判断插入操作是否导致了这一条链上结点的大小平衡被破坏,如果有的话将深度最浅的点所在子树暴力重建。重建最简单的方法就是对这棵子树中序遍历后分治建树。通过势能分析可以证明每一次插入的均摊复杂度为logn。
查询和普通BST并无区别。
删除操作比较巧妙。对于一次删除,我们并不马上移除这个点,而是直接这个点上打上删除标记,查询时跳过该点。重构时可以顺便删除打了删除标记的点。当被删除结点的个数超过总结点数的(1?α)倍时可以选择重构整棵树进行结构优化,并且显然这部分重构的复杂度不会超过O(nlogn)。
---------------------------------------------------------------------------------------------------------------------------------------------------
——以上内容蒯自xLightGod学长(http://blog.xlightgod.com/%E3%80%90bzoj3224%E3%80%91%E6%99%AE%E9%80%9A%E5%B9%B3%E8%A1%A1%E6%A0%91/)
以上是关于关于平衡树的一些总结的主要内容,如果未能解决你的问题,请参考以下文章