算法笔记——伸展树

伸展树是一种二叉搜索树,适用于快速插入、查找和删除操作。基于时间局部性和空间局部性原理,伸展树通过伸展操作(包括右旋和左旋)确保了操作的均摊效率。伸展操作分为逐层和双层,用于将访问节点移动到树根附近。此外,伸展树支持分裂和合并,区间操作以及常见查询。虽然在最坏情况下可能退化为链表,但其均摊时间复杂度仍为O(logn)。
摘要由CSDN通过智能技术生成

        伸展树,也叫作分裂树,是一种二叉搜索树,可以在O(logn)内完成插入、查找和删除操作。

在任意数据结构的生命周期内执行不同操作的概率往往极不均衡,而且各操作之间有极强的相关性,在整体上多呈现极强的规律性,其中最为典型的就是数据局部性。数据局部性包括时间局部性和空间局部性。伸展树正是基于数据的时间局部性和空间局部性原理产生的。

1、时间局部性和空间局部性的原理

(1)刚刚被访问的元素,极有可能在不久后再次被访问

(2)刚刚被访问的元素,它的相邻节点也很有可能被访问

        伸展树的实现更为便捷,它无须时刻保持全树平衡,任意节点的左右子树高差无限制。伸展树的单次搜索也可能需要n次操作,但可以在任意足够长的真实操作序列中保持均摊意义上的高效率O(logn)。伸展树可以保证m次连续搜索操作的复杂度为O(mlogn),而不是O(mn)。伸展树的优势在于不需要记录平衡因子、树高、子树大小等额外信息,所以适用范围更广,对m次连续搜索操作具有较高的效率。

        考虑到局部性原理,伸展树会在每次操作后都将被访问的节点旋转至树根,加速后续的操作。当然,旋转前后的搜索树必须相互等价。这样,查询频率高的节点应当经常处于靠近树根的位置。旋转的巧妙之处在于不打乱数列中数据大小的关系(中序有序性)的情况下,所有操作的均摊复杂度仍为O(logn)

2、右旋和左旋

伸展操作Splay(x,goal)是在保持伸展树有序性的前提下,通过一系列旋转将伸展树中的元素x调整到goal的子节点,若goal=0,则将元素x旋转到树的根部。伸展操作包括右旋和左旋两种基本操作。

与Treap的旋转方式相同,但左旋右旋可以写成一段代码。

void Rotate(int x)//x作为儿子出现
{
    int y=tr[x].fa,z=tr[y].fa;
    in
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值