简析平衡树(三)——浅谈Splay

本文介绍了Splay树的基本概念和特点,对比了它与其他平衡树的差异,强调了其伸展操作和区间翻转的能力。通过分析Splay树的旋转操作,分为三种情况讨论,展示其调整树形结构的过程。此外,文章通过两个模板题目,展示了Splay树在实现基本的二叉搜索树功能和维护区间翻转操作的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

原本以为 T r e a p Treap Treap已经很难了,学习了 S p l a y Splay Splay,我才知道,没有最难,只有更难。(强烈建议先去学一学 T r e a p Treap Treap再来看这篇博客)


简介

S p l a y Splay Splay是平衡树中的一种,除了平衡树所共有的作用之外,它还可以维护区间翻转,这也是它能成为 L C T LCT LCT辅助树的原因(不过 L C T LCT LCT并不是这篇博客所探讨的内容)。

因此,这篇博客将分为三个部分,第一个部分讲讲 S p l a y Splay Splay与其他平衡树的不同之处,另外两个部分则分别借助两道模板题,来讲讲 S p l a y Splay Splay两方面的作用。


S p l a y Splay Splay与其他平衡树的不同之处

s p l a y splay splay这个单词在百度翻译上的解释是张开。而在这里,则是指伸展(其实伸展张开差不多)。

S p l a y Splay Splay最重要的操作自然就是伸展操作了。

而伸展操作,则是建立于类似于 T r e a p Treap Treap R o t a t e Rotate Rotate旋转操作上的。

R o t a t e Rotate Rotate操作在简析平衡树(二)中已经介绍过了,这里就直接贴代码了:

inline void Rotate(int x,int &k)//好吧,两个Rotate操作还是有点区别的,因为Splay还要记录每个节点的父亲,这里的Rotate是要将x节点向上旋转一位,而k则是要旋转到的目标位置
{
   
	int fa=node[x].Father,grandpa=node[fa].Father,d=Which(x);//我们用fa记录当前节点的父亲,grandpa记录当前节点的祖父,d记录当前节点是父亲的哪一个儿子
	if(fa^k) node[grandpa].Son[Which(fa)]=x;//如果当前节点的父亲不是目标位置,那么更新当前节点祖父的儿子为当前节点
	else k=x;//否则说明已到达目标位置
	node[x].Father=grandpa,node[fa].Son[d]=node[x].Son[d^1],node[node[x].Son[d^1]].Father=fa,node[x].Son[d^1]=fa,node[fa].Father=x,PushUp(fa),PushUp(x);//这个与Treap中的操作差不多,先将当前节点的父亲更新为当前节点的祖父,并将当前节点原先父亲这一位的儿子更新为当前节点与这个方向相反的儿子,并将当前节点原先的父亲更新为当前节点的儿子,最后记得更新节点信息
}

S p l a y Splay Splay的主要功能,就是通过不断地 R o t a t e Rotate Rotate,使某一节点旋转至目标位置。

我们可以对 S p l a y Splay Splay每次的旋转操作进行分类讨论:

这里写图片描述

第一种情况, f a fa fa即为目标位置,此时只要上旋 x x x即可到达目标位置。

这里写图片描述

第二种情况, x x x, f a fa fa, g r a n d p a grandpa grandpa在同一直线上,且 f a fa fa不为目标位置。此时,我们需要将 f a fa fa上旋,同时带动 x x x上旋,然后再上旋一遍x。

这里写图片描述

第三种情况, x x x, f a fa fa, g r a n d p a grandpa grandpa不在同一直线上,且 f a fa fa不为目标位置。此时,我们直接将 x x x上旋,将 x x x的父亲更新为它的祖父 g r a n d p a grandpa grandpa,然后再上旋一遍 x x x即可。

具体代码实现如下:

inline void Splay(int x,int &k)//将x一直旋转到目标位置k
{
   
	for(int fa=node[x].Father;x^k;fa=node[x].Father)//重复循环,直至x为k
	{
   
		if(fa^k) Rotate(Which(fa)^Which(x)?x:fa,k);//如果fa不是目标位置,若x,fa,grandpa在同一直线上,我们需要将fa上旋,否则,直接将x上旋
		Rotate(x,k);//归纳可以得出,不管什么情况下都要将x上旋
	}
}

讲完了 S p l a y Splay Splay与其他平衡树的不同之处,后面的就很简单了。


模板1:【洛谷3369】【模板】普通平衡树

这应该是我第三次用到这个模板了&

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值