伸展树(Splay Tree)的深度理解
伸展树作为一种非常受欢迎的数据结构,其最初的想法(标记为想法一)是通过变换树的结构将最近访问的元素置于树根,倘若一系列操作都是和该元素有关,那么在变成树根之后将极大的提高该元素的访问速度。基于该想法,每次访问该元素时,沿着访问路径,逐层进行简单的单层旋转,从而使该元素的深度减小,最后变成树根。

实际应用中,多次连续的操作也可能是访问不同的元素,所以不得不考虑其他元素的访问速率问题。所以进一步的想法(标记为想法二)是,如果在树根化的过程中,能够使树的整体结构更加平衡,那么不仅可以把当前元素置于树根,而且也方便了其他元素的访问。
但是,大家不要对想法二想得过于完美。因为目标元素的树根化过程只和路径上的元素息息相关。所以想法二中的平衡只是针对路径上的元素,而其他元素的平衡问题就“照顾”不到了。
那么路径上的元素都被旋转到哪里了呢?
(本文的关键内容从这里开始)
不妨观察一下上面的单层旋转示意图,通过左旋,P节点变换到了V节点的右边,也就是说进入到了V节点的右子树(也就是b块),这个时候如果下一次旋转又是一个左旋,P又会进入到b块中。那么考虑到一般的情形,如果连续的遇到左旋(或者右旋),那么b块(或者a块)就会变得“臃肿”,使得变换后的树结构不平衡。如果是遇到“左右左右左右左右…”的情况,a块和b块就会相对平衡一些,单层旋转是行得通的,但是这种好的情况的出现是小概率的。所以在一般情况下,单层旋转的策略表现非常差劲。
<