除了AVL树,本章将按照二叉搜索树的介绍,继续介绍平衡二叉搜索树家族中的另一个成员—Splay伸展树。
相对于AVL,Splay的实现更为简捷。伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率。伸展树也不需要对基本的二叉树节点结构,做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广。
通常在任意数据结构的生命期内,执行不同操作的概率往往极不均衡,而且各操作之间具有极强的相关性,并在整体上多呈现出极强的规律性。其中最为典型的,就是所谓的“数据局部性”(data locality),这包括两个方面的含义:
- 刚刚被访问过的元素,极有可能在不久之后再次被访问到
- 将被访问的下一元素,极有可能就处于不久之前被访问过的某个元素的附近
如果将该策略应用于二叉搜索树。只需将刚被访问的节点,及时地“转移”至树根(附近),即可加速后续的操作。当然, 转移前后的搜索树必须相互等价,故为此使用前文介绍的“旋转“等价变换的技巧。
逐层伸展
每访问过一个节点之后,随即反复地以它的父节点为轴,经适当的旋转将其提升一层,直至最终成为树根。以下图为例,若深度为3的节点E刚被访问–无论查找或插入,甚至“删除”都可通过3次旋转,将该树等价变换为以E为根的另一棵二叉搜索树