Splay树旋转算法:为什么使用zig-zig和zig-zag而不是更简单的旋转?

时间:2012-04-10 22:21:07

标签: data-structures tree rotation splay-tree tree-balancing

我不太明白为什么展开树数据结构中的旋转不仅考虑了评级节点的父节点,还考虑了祖父节点(zig-zag和zig-zig操作)。为什么以下不起作用:

例如,当我们向树插入新节点时,我们检查是否插入左侧或右侧子树。如果我们插入左侧,我们将结果右旋转,反之亦然右侧子树。递归它会像这样

Tree insert(Tree root, Key k){
    if(k < root.key){
        root.setLeft(insert(root.getLeft(), key);
        return rotateRight(root);
    }
    //vice versa for right subtree
}

那应该避免整个“展开”程序,你不觉得吗?

1 个答案:

答案 0 :(得分:4)

你在树上提出的算法被称为“移动到根”启发式并被讨论on page four of Sleator and Tarjan's original paper on splay trees.他们引用了Allen和Munro的旧论文,其中显示如果你试图使用移植到root作为重塑树的手段,每次查找的摊销成本可能是O(n),这是非常慢的。 Splaying是一种非常精心设计的重塑树的算法,无论执行何种访问顺序,它都能保证分摊的O(log n)查找。

直观地说,移植到root不是重塑树的一种非常好的方法,因为它会沿着路径上的所有节点向下移动,从节点到根,同时尝试使访问节点在将来更容易到达。因此,在执行此版本的树重组时,整个树可能会变得更糟。另一方面,splay方法倾向于降低splayed节点和其访问路径上的所有节点的高度,这意味着整个树在展开期间往往会变得更好。

希望这有帮助!