您的位置:首页 > 其它

伸展树splay tree

2012-08-30 16:45 267 查看
伸展树实际上还是二叉查找树。

展树,或者叫自适应查找树,是一种用于保存有序集合的简单高效的数据结构。伸展树实质上是一个二叉查找树。允许查找,插入,删除,删除最小,删除最大,分割,合并等许多操作,这些操作的时间复杂度为O(logN)。由于伸展树可以适应需求序列,因此他们的性能在实际应用中更优秀。

假设想要对一个二叉查找树执行一系列的查找操作。为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法, 在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。splay tree应运而生。splay tree是一种自调整形式的二叉查找树,它会沿着从某个节点到树根之间的路径,通过一系列的旋转把这个节点搬移到树根去。

伸展树支持所有的二叉树操作。伸展树不保证最坏情况下的时间复杂度为O(logN)。伸展树的时间复杂度边界是均摊的。尽管一个单独的操作可能很耗时,但对于一个任意的操作序列,时间复杂度可以保证为O(logN)。

二、自调整和均摊分析:

平衡查找树的一些限制:

1、平衡查找树每个节点都需要保存额外的信息。

2、难于实现,因此插入和删除操作复杂度高,且是潜在的错误点。

3、对于简单的输入,性能并没有什么提高。

平衡查找树可以考虑提高性能的地方:

1、平衡查找树在最差、平均和最坏情况下的时间复杂度在本质上是相同的。

2、对一个节点的访问,如果第二次访问的时间小于第一次访问,将是非常好的事情。

3、90-10法则。在实际情况中,90%的访问发生在10%的数据上。

4、处理好那90%的情况就很好了。

三、均摊时间边界:

在一颗二叉树中访问一个节点的时间复杂度是这个节点的深度。因此,我们可以重构树的结构,使得被经常访问的节点朝树根的方向移动。尽管这会引入额外的操作,但是经常被访问的节点被移动到了靠近根的位置,因此,对于这部分节点,我们可以很快的访问。根据上面的90-10法则,这样做可以提高性能。

为了达到上面的目的,我们需要使用一种策略──旋转到根(rotate-to-root)。具体实现如下:

旋转分为左旋和右旋,这两个是对称的。图示:



为了叙述的方便,上图的右旋叫做X绕Y右旋,左旋叫做Y绕X左旋。

下图展示了将节点3旋转到根:



图1

首先节点3绕2左旋,然后3绕节点4右旋。

注意:所查找的数据必须符合上面的90-10法则,否则性能上不升反降!!

四、基本的自底向上伸展树:

应用伸展(splaying)技术,可以得到对数均摊边界的时间复杂度。

在旋转的时候,可以分为三种情况:

1、zig情况。

X是查找路径上我们需要旋转的一个非根节点。

如果X的父节点是根,那么我们用下图所示的方法旋转X到根:



图2

这和一个普通的单旋转相同。

2、zig-zag情况。

在这种情况中,X有一个父节点P和祖父节点G(P的父节点)。X是右子节点,P是左子节点,或者反过来。这个就是双旋转。

先是X绕P左旋转,再接着X绕G右旋转。

如图所示:



图三

3、zig-zig情况。

这和前一个旋转不同。在这种情况中,X和P都是左子节点或右子节点。

先是P绕G右旋转,接着X绕P右旋转。

如图所示:



图四
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: