//Treap的动态平衡树
#include<cstdio>
#include<cstdlib>
struct Node{
Node *ch[2]; //左右子树
int r; //优先级。数值越大,优先级越高
int v; //值
/* bool operator >(const Node& rhs)const { // 根据优先级比较结点
return r>rhs.r;
}
*/ int cmp(int x)const{
if(x==v) return -1;
return x<v?0:1;
}
};
//d=0代表左旋,d=1代表右旋
void rotate(Node* &o,int d){
Node *k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o=k;
}
//在以o为根的子树中插入键值x,修改o
void insert(Node* &o,int x){
if(o==NULL)
{
o=new Node(); o->ch[0]=o->ch[1]=NULL; o->v=x; o->r=rand();
}
else
{
int d=o->cmp(x); //若可能有相同点,则不用cmp函数 int d=(x<o->v?0:1);
insert(o->ch[d],x);
if(o->ch[d]->r>o->r)
rotate(o,d^1);
}
};
void remove(Node* &o,int x){
int d=o->cmp(x);
if(d==-1){
Node *u=o;
if(o->ch[0]==NULL) { o=o->ch[1]; delete u; }
else if(o->ch[1]==NULL) { o=o->ch[0]; delete u;}
else{
int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
rotate(o,d2);
remove(o->ch[d2],x);
}
}
else
remove(o->ch[d],x);
}
//上面的代码没有处理"待插入值已经存在"和"待删除值不存在"这两种情况
//因此在调用相应函数之前如必要可进行一次查找
int find(Node *o,int x){
while(o!=NULL){
int d=o->cmp(x);
if(d==-1)
return 1; //存在
else o=o->ch[d];
}
return 0; //不存在
}
void removetree(Node *&x)
{
if(x->ch[0]!=NULL) removetree(x->ch[0]);
if(x->ch[1]!=NULL) removetree(x->ch[1]);
delete x;
x=NULL;
}
int main()
{
int n,i,x;
Node *o=NULL;
freopen("e:\\in.txt","r",stdin);
while(scanf("%d",&n)==1)
{
for(i=1;i<=n;i++)
{
scanf("%d",&x);
if(find(o,x)==0)
insert(o,x);
else
printf("%d元素已存在!\n",x);
}
printf("插入完成\n");
remove(o,12);
for(i=1;i<=n;i++)
{
if(find(o,10+i)!=0)
{
printf("%d元素已存在!\n",10+i);
}
}
removetree(o);
for(i=1;i<=n;i++)
{
if(find(o,10+i)!=0)
{
printf("%d元素已存在!\n",10+i);
}
}
}
return 0;
}
Treap的动态平衡BST
最新推荐文章于 2024-09-27 13:48:59 发布