#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define keytree ch[ch[root][1]][0]
#define L(x) ch[x][0]
#define R(x) ch[x][1]
#define N 100010
int ch[N][2],pre[N],cnt[N],size[N],key[N];
int tot,root;
int a[N],n;
void newnode(int &u,int fa,int KEY)
{
u=++tot;
ch[u][0]=ch[u][1]=0;
pre[u]=fa;cnt[u]=size[u]=1;
key[u]=KEY;
}
void up(int x)
{
if(x)
{
size[x]=cnt[x];
if(ch[x][0])size[x]+=size[ch[x][0]];
if(ch[x][1])size[x]+=size[ch[x][1]];
}
}
void rotate(int u,int kind)//kind表示u在fa的哪一边
{
int fa=pre[u];
ch[fa][kind]=ch[u][!kind];
pre[ch[u][!kind]]=fa;
if(pre[fa])ch[pre[fa]][ch[pre[fa]][1]==fa]=u;
pre[u]=pre[fa];
ch[u][!kind]=fa;
pre[fa]=u;
up(fa);up(u);
}
void splay(int u,int goal)
{
int fa,kind;
while(pre[u]!=goal)
{
if(pre[pre[u]]==goal)
{
rotate(u,R(pre[u])==u);
}
else
{
fa=pre[u];
kind=R(pre[fa])==fa;
if(ch[fa][kind]!=u)//不在同一侧
{
rotate(u,!kind);
rotate(u,kind);
}
else
{
rotate(fa,kind);
rotate(u,kind);
}
}
}
up(u);
if(goal==0)root=u;
}
void insert(int v)
{
if(root==0)
{
newnode(root,0,v);
return;
}
int now=root,fa=0;
while(1)
{
if(key[now]==v)
{
cnt[now]++;up(now);up(fa);splay(now,0);
break;
}
fa=now;
now=ch[now][key[now]<v];
if(now==0)
{
newnode(ch[fa][key[fa]<v],fa,v);
up(fa);splay(ch[fa][key[fa]<v],0);
break;
}
}
}
int getkth(int u,int k)//第k个键值的点的编号
{
int s=size[L(u)]+cnt[u];
if(size[L(u)]<k&&k<=s) return u;
if(s-cnt[u]>=k) return getkth(L(u),k);
else return getkth(R(u),k-s);
}
int find(int u,int x)//查找键值为x的点的编号
{
if(key[u]==x)return u;
if(key[u]>x)
{
if(!L(u))return -1;
return find(L(u),x);
}
if(key[u]<x)
{
if(!R(u))return -1;
return find(R(u),x);
}
}
int getpre(int u)
{
if(cnt[u]>=2)return u;
u=L(u);
while(R(u))u=R(u);
return u;
}
int getnext(int u)
{
if(cnt[u]>=2)return u;
u=R(u);
while(L(u))u=L(u);
return u;
}
void del(int x)//删除编号为x的节点
{
if(size[root]==1)
{
root=0;
return ;
}
if(cnt[x]>1)
{
cnt[x]--;
return ;
}
splay(x,0);
if(L(root))
{
if(!R(root))
{
pre[L(root)]=0;
root=L(root);
return ;
}
int p=getpre(x);
splay(p,root);
R(p)=R(root);
pre[R(root)]=p;
root=p;
pre[p]=0;
up(root);
}
else
{
root=R(root);
pre[root]=0;
}
}
//--------------------------------------------------基本操作 splay模板 (权值建树)
最新推荐文章于 2024-07-15 16:02:10 发布
本文介绍了一种基于二叉搜索树的数据结构实现方法,包括插入、查找、删除等基本操作,并详细解释了旋转、调整平衡等关键技术。
1261

被折叠的 条评论
为什么被折叠?



