- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
伸展树的原理及应用
伸展树的原理及应用
常州市第一中学 林厚从
【】【】需要额外的空间来存储平衡信息,且实现起来比较复杂。同时,如果访问模式不均匀,平衡树的效率就会受到影响。而伸展树却可以克服这些问题。
伸展树(Splay Tree),是由Daniel Sleator和Robert Tarjan创造,也是对二叉查找树的一种改进。虽然它并不能保证树一直是“平衡”的,但对于它的一系列操作,可以证明其每一步操作的“平摊时间”复杂度都是O(log2n),平摊时间是指在一系列最坏情况的操作序列中单次操作的平均时间。所以从某种意义上说,伸展树也是一种平衡的二叉查找树。而在各种树状数据结构中,伸展树的空间要求(不需要记录用于平衡的冗余信息)和编程复杂度也都是很优秀的。
获得较好平摊效率的一种方法就是使用“自调整”的数据结构。与平衡结构或有明确限制的数据结构相比,自调整的数据结构有以下几个优点:
1、从平摊角度来说,它们忽略常量因子,因此绝对不会差于有明确限制的数据结构。而且由于它们可以根据具体使用情况进行调整,所以在使用模式不均匀的情况下更加有效;
2、由于无需存储平衡信息或者其它限制信息,所以所需的存储空间更小;
3、它们的查找和更新算法概念和操作都很简单,易于实现。
当然,自调整结构也有其潜在的缺点:
1、它们需要更多的局部调整,尤其是在查找期间。而那些有明确限制的数据结构仅需要在更新期间进行调整,查找期间则不用;
2、一系列查找操作中的某一个可能会耗时较长,这在实时应用程序中可能是一个不足之处。
【】
图 1、ZIG或ZAG
图 2、ZIG-ZIG
情况二:结点x的父结点y不是根结点。则我们设y的父结点为z,且x与y同时是各自父结点的左孩子、或者同时是各自父结点的右孩子。这时,我们进行一次Zig-Zig操作、或者Zag-Zag操作。如图2所示:
情况三:结点x的父结点y不是根结点。则我们设y的父结点为z,且x与y中一个是其父结点的左孩子、而另一个是其父结点的右孩子。这时,我们进行一次Zig-Zag操作、或者Zag-Zig操作。如图3所示:
图 3、ZIG-ZAG
下面举一个例子来体会上面的伸展操作。如图4所示,最左边的一个单链先执行Splay(1,S),我们将元素1调整到了伸展树S的根部。如图5所示,再执行Splay(2,S),将元素2调整到了伸展树S的根部。从直观上可以看出在经过调整后,伸展树比原来“平衡”了许多。而伸展操作的过程并不复杂,只需要根据上述三种情况进行旋转就可以了,而三种旋转都是由基本的左旋和右旋组成的,实现较为简单。
图4、Splay(1,S)
图5、Splay(2,S)
二、伸展树的基本操作
利用Splay操作,我们可以在伸展树S上进行如下几种基本运算。
1、Find(x,S):判断元素x是否在伸展树S表示的有序集中。
首先,与在二叉查找树中进行的查找操作一样,在伸展树中查找元素x。如果x在树中,则再执行Splay(x,S)调整伸展树。
2、Insert(x,S):将元素x插入到伸展树S表示的有序集中。
首先,与在二叉查找树中进行插入操作一样,将x插入到伸展树S中的相应位置,再执行Splay(x,S) 调整伸展树。
3、Join(S1,S2):将两棵伸展树S1与S2合并成为一棵伸展树。其中S1的所有元素都小于S2的所有元素。
首先,找到伸展树S1中最大的一个元素x,再通过Splay(x,S1)将x调整到伸展树S1的根。然后再将S2作为x结点的右子树,这样就得到了新的伸展树S。如图6所示:
图6、Join(S1,S2)
4、Delete(x,S):将元素x从伸展树S所表示的有序集中删除。
先执行Find(x,S)将x调到根,然后再对左右子树执行Join(S1,S2)。
5、Split(x,S):以x为界,将伸展树S分离为两棵伸展树S1和S2,其中S1中所有元素都小于x,S2中的所有元素都大于x。
首先执行Find(x,S),将元素x调整为伸展树的根结点,则x的左子树就是S1,而右子树就是S2。如图7所示:
图7、Split(x,S)
除了上面介绍的五种基本操作外,伸展树还支持求最大值、求最小值、求前趋、求后继等多种操作,这些基本操作也都是建立在伸展操作的基础上的。
三、伸展树的基本操作的算法实现
1、伸展树类型的定义
Type
Tpoint=^Trec;
Trec=Record
Key:integer; //关键字
Father,LeftChild,RightChild:Tpoint; //父结点、左孩子、右孩子
End;
Var
S:Tpoint;
文档评论(0)