Splay
来源:互联网 发布:大数据的弱点 编辑:程序博客网 时间:2024/04/24 20:33
思想
Splay_tree,伸展树,顾名思义就是用伸展来进行平衡的平衡树。伸展操作是把一个节点伸展到根上的操作,当然不是简单的旋转到根,而是:(绿色节点是x,蓝色节点为p,红色节点为g)
①当p是根节点时,只需要一次正常的旋转即可。
②当p不是根节点,x,p,g“三点共线”时,先旋转p,然后旋转x。
③当p不是根节点,x,p,g“三点不共线”时,旋转两次x。
每次插入,询问,删除,合并,分裂后,都需要伸展。可以证明得到每次操作均摊复杂度是log2(n),但是单次操作复杂度可能较高(比如在好多次伸展后变成了链,那么单次复杂度就变成了O(n),但链会被接下来的伸展打破,下次操作可能比log2(n)还小)。
插入,询问,删除都是常规的(只不过之后要伸展),这里就讲讲合并和分裂。
合并:
①当S1中的所有元素小于S2(比如S1和S2是刚刚分裂出来的)时,只需要把S1最大的点伸展到根,然后连边即可。
②当S1和S2大小任意时,启发式合并,把小的往大的身上挪。
分裂:(以k为界限,左边小于或等于k,右边大于或等于k)
只需要把k伸展到根,然后根据情况断开连接即可。
ps:学过Treap以后,不难写出代码,这里就不给出了(我才不会告诉你们是我写模板没debug成功T_T),只给出一个伸展操作:
void Splay(P_node &id,int k) //请确保k存在{ int d1=id->cmp(k); if (d1!=-1) { P_node p=id->son[d1]; int d2=p->cmp(k); if (d2!=-1) { Splay(p->son[d2],k); //先递归处理下面 if (d1==d2) Rotate(id,d1^1),Rotate(id,d1^1); else //三点共线 Rotate(id->son[d1],d2^1),Rotate(id,d1^1); //三点不共线 } else Rotate(id,d1^1); //旋转一次 } }
1 0
- SPLAY
- splay
- splay
- splay
- Splay
- Splay
- splay
- splay
- splay
- splay
- Splay
- splay
- Splay
- splay
- Splay
- Splay
- splay
- Splay大功告成
- c++作业报告1
- 把项目放到码云上,通过git 进行项目管理
- CS231n Assignment1--Q1
- 使用crypoto++进行加密解密签名和认证心得
- 从全景相机领先者到大幅裁员,完美幻境经历了什么?
- Splay
- 企业级别javaweb开发框架
- (一)数据结构中的基本概念
- 平板电脑的互联网串口通信
- VS设置同时启动多个项目
- STL之Vector
- JS创建对象几种不同方法详解
- HashMap实现原理
- 165. Compare Version Numbers