伸展树

来源:互联网 发布:男生衣服品牌 知乎 编辑:程序博客网 时间:2024/05/16 15:52

概念

伸展树是一种二叉查找树,具有二叉查找树的性质.而与二叉查找树相比,伸展树具有的特点是:当某个节点被访问时,伸展树会通过旋转使该节点成为树根。

伸展树操作的时间复杂度较低的原因是:把访问频率高的结点放在根节点附近

伸展树的旋转算法

伸展树的重点在与旋转算法,有三种旋转类型:

  • zig
  • zig-zig
  • zig-zag

设有结点x,p是x的父母结点,g是p的父母结点

zig:当p是根节点,旋转类型为zig

这里写图片描述

zig-zig:当p不是根节点,且x和p均为右孩子结点,或左孩子结点

这里写图片描述

这种情况下,p先向右旋转,然后x向右旋转即可将x结点旋转至根结点

zig-zag:当p不是根节点,且x,p分别为右孩子结点和左孩子结点,或者左孩子结点和右孩子结点

这里写图片描述

在这种情况下,x先向左旋转,然后向右旋转

基本操作

Find

先调用普通二叉搜索树的Find函数找到对应结点
对找到结点调用splay函数,使该结点成为根节点
返回根节点

伪代码实现

STFind(x, R)    N <--- Find(x, R)    Splay(N)    return N

Insert

像普通二叉搜索一样插入元素x
调用splay函数,使刚插入的元素x成为根节点
伪代码实现

STInsert(x, R)    Insert(x, R)    STFind(x, R)

Delete

调用Next(x)找到大于x的最小结点
调用splay(Next(x))将找到的结点旋转至根节点
调用splay(x)将要删除的结点旋转至根节点
调用普通二叉搜索树的删除函数delete删除根节点

伪代码实现

STDelete(x)    splay(Next(x))    splay(x)    Delete(x)

split

调用是splay(x)函数,将x旋转至根节点,此时根节点的左子树的元素均小于x,右子树均大于元素x
右子树为R2,剩下部分为R1

伪代码实现

STSplit(x)   N <--- Find(x, R)   splay(N)   R2 <--- right subtree of R   R1 <--- the rest of the tree   return (R1, R2)

Merge

调用Find(max, S)找出小树S中的最大元素x
调用splay(x),此时小树S中没有了右子树
把大树T当做S的右子树即可

STMerge(S, T)    x = Find(max, S)    splay(x)    S.Right <--- T    return S 
0 0