1.右旋(zig)
void _zig(int x)
{
int y,z;
y=pr[x];
z=pr[y];
if(z==0)
root=x;
else if(ls[z]==y)
ls[z]=x;
else
rs[z]=x;
pr[x]=z;
pr[y]=x;
ls[y]=rs[x];
pr[rs[x]]=y;
rs[x]=y;
size[x]=size[y];
size[y]=size[ls[y]]+size[rs[y]]+1;
}
2.左旋(zag)
void _zag(int x)
{
int y,z;
y=pr[x];
z=pr[y];
if(z==0)
root=x;
else if(ls[z]==y)
ls[z]=x;
else
rs[z]=x;
pr[x]=z;
pr[y]=x;
rs[y]=ls[x];
pr[ls[x]]=y;
ls[x]=y;
size[x]=size[y];
size[y]=size[ls[y]]+size[rs[y]]+1;
}
3.splay旋转(平衡性较好的一种写法)
void _splay(int x)
{
int j;
while(x!=root)
{
j=pr[x];
if(j==root)
{
if(x==ls[j])_zig(x);
else _zag(x);
}
else
{
if(j==ls[pr[j]])
{
if(x==ls[j]){_zig(j);_zig(x);}
else {_zag(x);_zig(x);}
}
else
{
if(x==rs[j]){_zag(j);_zag(x);}
else {_zig(x);_zag(x);}
}
}
}
}
4.插入(insert)(记了左右子节点数量的一种写法,便于查找第k小)
void _insert(int key)
{
int i=root;
if(size[i]==0)
{
data[i]=key;
pr[i]=0;
size[i]=1;
tot++;
return;
}
if(_find(key)==-1)
{
while(true)
{
if(key<data[i])
{
if(ls[i]!=0)
{
size[i]++;
i=ls[i];
}
else
{
pr[tot]=i;
data[tot]=key;
ls[i]=tot;
size[tot]=1;
size[i]++;
tot++;
return;
}
}
else if(key>data[i])
{
if(rs[i]!=0)
{
size[i]++;
i=rs[i];
}
else
{
pr[tot]=i;
data[tot]=key;
rs[i]=tot;
size[tot]=1;
size[i]++;
tot++;
return;
}
}
else
{
_splay(i);
return;
}
}
}
}
5.删除(del)
void _del(int key)
{
int x,y=0,z=0;
x=_find(key);
if(x==-1)
return;
_splay(x);
y=_findpre(x);
if(y!=0)
{
_splay(y);
rs[y]=rs[x];
pr[rs[x]]=y;
size[y]--;
root=y;
}
else
{
z=rs[x];
pr[z]=0;
root=z;
}
}
6.查找(find)
int _find(int key)
{
int i=root;
while(i!=0)
{
if(key<data[i])
i=ls[i];
else if(key>data[i])
i=rs[i];
else
return i;
}
return -1;
}
7.找前驱(findpre)
int _findpre(int x)
{
int i;
if(x!=root)
_splay(x);
i=ls[x];
while(rs[i]!=0) i=rs[i];
return i;
}
8.找后继(findnex)
int findnex(int key)//返回值为key的后继的下标
{
int k=root,ans=0;
while(k)
if(key>data[k])k=rs[k];
else{
ans=k;
k=ls[k];
}
return ans;
}
9.找第k小数(findkth)
int _findkth(int x)
{
int i=root;
while(i!=0)
{
if(ls[i]!=0&&x<=size[ls[i]])
i=ls[i];
else if(x>size[ls[i]]+1)
{
x-=size[ls[i]]+1;
i=rs[i];
}
else
return data[i];
}
if(i==0)
return 0;
}