伸展树(Splay Tree)进阶 - 从原理到实现再到应用


1 简介

伸展树(Splay Tree),是一种二叉搜索树(Binary Search Tree,又称二叉排序树Binary Sort Tree),由丹尼尔·斯立特(Daniel Sleator)和 罗伯特·恩卓·塔扬(Robert Endre Tarjan)在1985年发明。

平衡的二叉搜索树一般分为两类:

  严格维护平衡的,树的高度控制在$\log _2 n$,使得每次操作都能使得时间复杂度控制在$O\left( {\log n} \right)$,例如AVL树,红黑树;

  非严格维护平衡的,不能保证每次操作都控制在$O\left( {\log n} \right)$,但是每次操作均摊时间复杂度为$O\left( {\log n} \right)$,例如伸展树。

伸展树的优点在于无需记录额外的值来维护树的信息,同时支持的操作很多;

伸展树的缺点主要在于速度慢,最坏情况可能使得树退化成一条链;


2 基本操作

2.1 旋转

旋转操作,它可以使得某一个结点提升到他父亲的位置而不破坏平衡二叉树的性质。

如下图,很好地展现了ZIG旋转和ZAG旋转的具体操作:

图2.1 ZIG旋转和ZAG旋转

在图2.1中,$x$ 和 $y$ 分别代表两个节点,$A,B,C$ 分别代表三棵子树,

显然它们满足性质:对于任意一个节点,它大于等于其左子树中的任何一个节点,并且小于等于其右子树中的任何一个节点。

那么,易知ZIG旋转和ZAG旋转不会破坏上述性质;

不妨称 ZIG($x$) 为将 $x$ 节点右旋,ZAG($y$) 为将 $y$ 节点左旋

具体如何实现ZIG操作和ZAG操作,很简单:

2.1.1 ZIG操作

ZIG($x$):将 $x$ 节点的右子树 $B$ 拿开,将 $y$ 节点变为 $x$ 节点的右儿子,再把子树 $B$ 变为 $y$ 节点的左子树。

2.1.2 ZAG操作

ZIG($y$):将 $y$ 节点的左子树 $B$ 拿开,将 $x$ 节点变为 $y$ 节点的左儿子,再把子树 $B$ 变为 $x$ 节点的右子树。

猜你喜欢

转载自www.cnblogs.com/dilthey/p/9379652.html