[转]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 优点:每次查询会调整树的结构,使被查询频率 ...
随机推荐
- mac下zsh的使用:主题、z命令
安装Oh-My-ZSH: `curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh` zs ...
- 【BZOJ】【2434】【NOI2011】阿狸的打字机
AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...
- Informatica 常用组件Lookup之二 已连接和未连接的查找
可以配置一个已连接的查找转换,以从映射管道中直接接收输入:您也可以配置一个未连接的查找转换,以从其它转换的表达式结果中接收输入. 已连接的查找 未连接的查找 直接从管道接收输入值. 从其它转换的 :L ...
- (转)看懂UML类图和时序图
从一个示例开始 请看以下这个类图,类之间的关系是我们需要关注的: 车的类图结构为<<abstract>>,表示车是一个抽象类: 它有两个继承类:小汽车和自行车:它们之间的关系为 ...
- 理解JavaScript里this关键字
1.全局代码中的this:始终指向window 2.函数代码中的this: }; var bar = { x: , test: function () { alert(this === bar); a ...
- C++:cin、cin.getline()、getline()的用法
主要内容: 1.cin用法 2.cin.getline()用法 3.getline()用法 3.注意的问题 一.cin>> 用法1:输入一个数字或字符 #include <iostr ...
- 自己的一个js库
https://github.com/sqqihao/nono_framework.git 持续更新,慢慢写着,这样才能成长
- URLRewriter.dll的使用
http://www.cnblogs.com/Jaylong/archive/2011/10/17/url.html 微软URLRewriter.dll的url重写的简单使用 先添加引用URLRewr ...
- 子查询一(WHERE中的子查询)
子查询 子查询就是指的在一个完整的查询语句之中,嵌套若干个不同功能的小查询,从而一起完成复杂查询的一种编写形式,为了让读者更加清楚子查询的概念. 子查询返回结果子查询可以返回的数据类型一共分为四种: ...
- windows XP系统搜索无线网络时提示“windows无法配置此无线连接”,如何处理?
转自:http://support1.lenovo.com.cn/lenovo/wsi/htmls/detail_12839009034375918.html 文章编号:C191612 201 ...