splay单旋双旋对比

splay单双旋还挺有意思的,一直觉得单旋是ok的,但是感性画图分析了一波~

单旋:直接旋转我自己

双旋:先旋转我的父亲,再旋转我自己

对于链结构,我们需要双旋,画图之后发现,我们采用双旋会至少压一层,而单旋则一直维持链式结构,显然单旋会被卡成O(n)

其余的结构而言,单旋双旋并无多大区别,但需要注意的是,双旋也存在一种结构被卡,但卡成连后就会被压层,而单旋则可能一直被卡,因此均摊复杂度还是log2(n)

详细的复杂度证明Tarjan用到了势能这个概念orz,具体有兴趣的同学可以上网查一查

struct Splay{
	#define N 100010
	int k[N]siz[N];
	int rt,cnt,p[N],ch[N][2];
	#define Ls(v) ch[v][0]
	#define rs(v) ch[v][1]
	inline void maintain(int x){
		siz[x]=siz[Ls(x)]+siz[rs(x)]+1;
	}
	inline void rot(int x){
		int f=p[x],gf=p[f],type=rs(f)==x,son=ch[x][!type];
		ch[p[son]=f][type]=son,maintain(f);
		ch[p[f]=x][!type]=f,maintain(x);
		ch[p[x]=gf][rs(gf)==f]=x;
	}
	inline void splay(int x,int goal){//旋转在目标的下面 
		if(x==goal)return ;
		while(p[x]^goal){
			if((p[p[x]]^goal)&&((rs(p[p[x]])==p[x])==(rs(p[x])==x)))rot(p[x]);
			rot(x);
		}
		if(!goal)rt=x;
	}
};

可读性还是蛮高的……其实我不是压行选手~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值