[转]Splay Tree
转自:http://blog.sina.com.cn/s/blog_7c4c33190100sg9r.html
Splay Tree(又叫伸展树)本质上也是一棵二叉查找树。它不是严格平衡的,但通过一种伸展(splay)操作可以使它一次操作的时间均摊复杂度为O(logN)。详细时间复杂度证明请参考集训队论文。这里,我只说说伸展树的实际操作。
和其他二叉查找树一样,Splay Tree支持查找询问、修改、加入、删除等操作,但又有所不同。
对于询问,每次找到目标值后,把目标位置伸展到根。
对于修改,与询问类似。
对于加入,如果是一个节点加入,则与上列相似。若是插入一个区间(一棵子树),可以把要插入地方的前一个节点伸展到根,把后一个节点伸展到根的右节点,这样就可以直接把那棵子树作为根节点的右节点的左子树了。
删除的原理与加入相同,都是把要删除的区间弄成(就是把前一个点伸展到根,后面第一个节点伸展到根的右节点)根节点的右节点的左子树,然后直接拿掉就行了。
(以上所有伸展操作指的都是splay操作)
以上所有操作都涉及到一个splay操作,那splay操作是什么呢?了解Treap的应该都明白用来维护树平衡的左旋和右旋操作,splay操作就是一系列的左旋和右旋操作。
为什么要进行splay操作呢?这样在询问后不是要用很多时间来splay?这样不是会增大时间的消耗吗?可是想想,如果多次询问一个很深的节点的话,每一次询问的复杂度都会接近N,这样二叉树就很容易超时。每一次都做splay后可以证明所有操作的均摊复杂度是O(logN),这样,就保持了二叉查找树的优美性。
那splay操作如何实现呢?
我们不妨设要伸展至根的节点为x,根为root,x的父亲是y,y的父亲是z。
首先,它分单选和双旋两种基本操作。
单选:当y是root的时候,直接用一个左旋或者右旋(Treap的操作,见附注)就可以把x伸展至根。
双旋:这就要分两种情况讨论了。
①:x和y同为它们父亲的左儿子或右儿子时,先把y旋到z,再把x旋到y。(同样是用左旋和右旋操作)
②:x和y不同为它们父亲的左儿子或右儿子时,把x做两个单旋。(左右旋操作)
为什么要有双旋的①操作呢?试想一下如果当前是一条链的话,在查询完最深的节点后,如果没有①的操作而只用N个单旋把节点单旋上去的话,splay操作后的树仍然是一条链,如图1-1至图1-5:
但若是用双旋的话情况就不同了,如图2-1至2-5:
在询问节点数很大的链时,双旋的优越性更明显。
以上操作可以通过调用一个子程序splay(root,x)完成,表示把x节点伸展到根。很明显,如果我们把root改成x到根路径上面的任意一个节点,就可以把x节点伸展到x到根的路径上任一位置。
附注:
可以看出,左旋和右旋适用于一棵二叉树中的任意一个节点,并且在旋转之后的二叉树保证合法性。
这里有一道Splay Tree的练手题,虽然它可以用时效性很高的树状数组做,也可以用线段树做,或者是其他的各种树做。。。但就当它只能用Splay Tree做好了。。。据说能过这题的Splay常数就不会太大。
http://www.cnblogs.com/zhsl/p/3189912.html
[转]Splay Tree的更多相关文章
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
- bzoj 3223/tyvj 1729 文艺平衡树 splay tree
原题链接:http://www.tyvj.cn/p/1729 这道题以前用c语言写的splay tree水过了.. 现在接触了c++重写一遍... 只涉及区间翻转,由于没有删除操作故不带垃圾回收,具体 ...
- 伸展树 Splay Tree
Splay Tree 是二叉查找树的一种,它与平衡二叉树.红黑树不同的是,Splay Tree从不强制地保持自身的平衡,每当查找到某个节点n的时候,在返回节点n的同时,Splay Tree会将节点n旋 ...
- [转] Splay Tree(伸展树)
好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...
- 树-伸展树(Splay Tree)
伸展树概念 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造. (01) 伸展树属于二 ...
- HDU-3436 Queue-jumpers 树状数组 | Splay tree删除,移动
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3436 树状数组做法<猛戳> Splay tree的经典题目,有删除和移动操作.首先要离散化 ...
- HDU1890 Robotic Sort Splay tree反转,删除
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题目中涉及数的反转和删除操作,需要用Splay tree来实现.首先对数列排序,得到每个数在数列 ...
- POJ-3468 A Simple Problem with Integers Splay Tree区间练习
题目链接:http://poj.org/problem?id=3468 以前用线段树做过,现在用Splay Tree A了,向HH.kuangbin.cxlove大牛学习了各种Splay各种操作,,, ...
- Splay Tree的删除操作
Splay Tree的插入操作,搜索操作,和删除操作都实现了,那么就能够使用来解题了. 指针的删除操作的处理还是那么难的,非常多坎须要避开. 同一个坎还是坑了我好多次,就是指针传递的问题,什么时候须要 ...
- Splay tree
类别:二叉排序树 空间效率:O(n) 时间效率:O(log n)内完成插入.查找.删除操作 创造者:Daniel Sleator和Robert Tarjan 优点:每次查询会调整树的结构,使被查询频率 ...
随机推荐
- ubuntu下如何查看软件安装目录以及安装版本
1)aptitude show 软件名 例如aptitude show kde-runtime 显示如下 ****@ubuntu:~$ aptitude show kde-runtime 软件包: k ...
- Git 学习(六)分支管理
Git 学习(六)分支管理 几乎每一种版本控制系统都支持分支.使用分支意味着你可以从开发主线上分离开来,然后不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录 ...
- 启明星产品与微软Active Directory活动目录集成说明
本文介绍启明星Helpdesk系统,如何和微软域集成. (1)确保在集成微软域之前,系统已经能够访问. (2)进入后台,用户管理页面,新加一个账户,此账户需要在微软域里(普通账户即可),然后在角色里设 ...
- OpenCV教程(41) 人脸特征检测
在OpenCV中,自带着Harr分类器人脸特征训练的文件,利用这些文件,我们可以很方面的进行人脸,眼睛,鼻子,表情等的检测. 人脸特征文件目录: ../opencv2.46/op ...
- sql server 将字符串分割成表函数 strsplitetotable
在sql server里,调用存储过程时,经常需要将数据拼成字符串做为参数调用存储过程,而在储存过程中分割字符串虽然简单但麻烦,封装了该函数,可以将拼串分割成内存表返回,方便使用,返回的表字段从a,b ...
- jquery中filter(fn)的使用研究
jquery中filter(fn)给出的官方说明是: 筛选出与指定函数返回值匹配的元素集合 这个函数内部将对每个对象计算一次 (正如 '$.each'). 如果调用的函数返回false则这个元素被删除 ...
- JavaScript Event Delegation, and event.target vs. event.currentTarget
原文:https://medium.com/@florenceliang/javascript-event-delegation-and-event-target-vs-event-currentta ...
- 通过page页面与portlet的结合实现报表的局部刷新
场景:系统已经存在两个报表,报表A与B,A与B之间可以通过省份进行追溯. 如下图:点击 报表[销售数据按区域]中的北京市 追溯到报表[销售数据按省份] 需求:让上面的操作在一个page里面刷新,实现页 ...
- List 去重对象
@Overridepublic RpcResponse<List<HobbiesVo>> queryHobbies(Long userId) { try{ List<Ho ...
- js 特效
栏目1 栏目1->菜单1 栏目1->菜单2 栏目1->菜单3 栏目1->菜单4 栏目2 栏目2->菜单1 栏目2->菜单2 栏目2->菜单3 栏目2-> ...