Splay(伸展)树学习笔记

本文介绍了Splay树,一种支持高效搜索的二叉平衡树,重点讲解了splay操作、旋转(包括左旋、右旋和双旋)以及C++代码实现,展示了如何通过旋转保持树的平衡性。

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

简介

splay树是一种二叉平衡树,支持splay操作;splay操作可以利用旋转使某个节点移动到某个祖父的位置,同时保持平衡树的性质。

旋转图解

1.左旋和右旋。该图为右旋(ZIG),反过来就是左旋(ZAG)。

 2.双旋。当x要移动到z时,要进行两次旋转若对x直接旋转两次后,低效的链式结构还是存在,我们需要尽量消除链。

 所以先对y旋转,再对x旋转,可以看到树的深度由3变为了2。

 代码实现

1.节点结构

​
#include<bits/stdc++.h>
#define Ls(x) T[x].ch[0]
#define Rs(x) T[x].ch[1]
#define Fa(x) T[x].fa
#define root  T[0].ch[0]
const int max = 10010;
int tot = 0;
struct node
{
	int fa;
	int ch[2];
	int size;//子节点的数量,包含本身。
	int cnt;//值出现的次数
	int val;//值
}T[max];

​

2.index 

 用于判断x是其父亲的左儿子还是右儿子

int index(int x)
{
	return T[Fa(x)].ch[0] == x ? 0 : 1;
}

3.rotate (旋转)

x成为祖父的哪个儿子与父亲是祖父的哪个儿子是一样的。

x的要改变爸爸的儿子是与index(x)^1,成为另一个爸爸的index(x)儿子。

x的爸爸变成了x的index(x)^1儿子

void connect(int x,int F,int way)
{
	T[x].fa = F;
	T[F].ch[way] = x;

}
void rotate(int x)
{
	int F=Fa(x), GrandF = T[Fa(x)].fa;
	connect(x, GrandF, index(Fa(x)));
	connect(T[x].ch[index(x) ^ 1], F, index(x));
	connect(F, x, index(x) ^ 1);

}

4.splay

void splay(int x,int to)
{
	while (x != to)
	{
		if (Fa(x) == to)
			rotate(x);
		else if (index(x) == index(Fa(x)))
			rotate(Fa(x)), rotate(x);
		else
			rotate(x), rotate(x);

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值