treap 排序二叉树的模板

来源:互联网 发布:ios基于linux还是unix 编辑:程序博客网 时间:2024/06/10 09:09


Description

有一个序列含有一定数量的元素,现在要求写一个程序,满足以下几个要求:【A】支持插入操作(这个序列不允许有重复元素,即是说,如果待插入的元素已经出现在这个序列中,那么请忽略此操作)【B】支持删除操作(如果此序列中不包含待删除的这个元素,则忽略此操作,否则删除这个元素)【C】查找元素x的前继元素(前继元素是指:小于x且与x最接近的元素,当然,如果x已经是序列中的最小元素,则x没有前继元素)【D】查找元素x的后继元素(后继元素是指:大于x且与x最接近的元素,当然,如果x已经是序列中的最大元素,则x没有后继元素)【E】找第K小的元素【F】求某个元素x的秩(即x的排名是多少,从小到大排序)
多组数据(整个文件以输入 -1 结束)对于每组数据,有若干行(最多100000行),表示的意义如下:【A】 insert x  【B】 delete x【C】 predecessor x【D】 successor x【E】 Kth x【F】 rank x这6种操作的意义与上面的定义相对应!【G】 print  表示从小到大输出序列中的所有元素【H】 end表示结束本组数据每组输入数据后有一空行!
对于以上8种操作,分别输出对应信息,如下:【A】 insert x  不用输出任何信息【B】 delete x  如果x存在,则删除x,否则输出 Input Error【C】 predecessor x  如果x不存在,输出 Input Error;否则如果x是序列中的最小元素,输出对应信息(见样例),否则输出x的前继元素【D】 successor x    如果x不存在,输出 Input Error;否则如果x是序列中的最大元素,输出对应信息(见样例),否则输出x的后继元素【E】 Kth x  如果x不合法,输出 Input Error;否则输出第Kth小的元素(见样例)【F】 rank x  如果x不存在,输出 Input Error;否则输出x的排名(见样例)【G】 print  从小到大输出序列中的所有元素,每个元素后加一个逗号,并在最后加上 end of print(见样例)【H】 end输出 end of this test
insert 20insert 5insert 1insert 15insert 9insert 25insert 23insert 30insert 35printKth 0Kth 1Kth 3Kth 5Kth 7Kth 9Kth 10rank 1rank 3rank 5rank 15rank 20rank 30rank 31rank 35successor 15successor 35successor 25successor 26predecessor 1predecessor 20predecessor 23predecessor 15predecessor 111delete 9delete 15delete 25delete 23delete 20printKth 3Kth 4rank 30rank 35end-1
1,5,9,15,20,23,25,30,35,end of printInput ErrorThe 1_th element is 1The 3_th element is 9The 5_th element is 20The 7_th element is 25The 9_th element is 35Input ErrorThe rank of 1 is 1_thInput ErrorThe rank of 5 is 2_thThe rank of 15 is 4_thThe rank of 20 is 5_thThe rank of 30 is 8_thInput ErrorThe rank of 35 is 9_thThe successor of 15 is 2035 is the maximumThe successor of 25 is 30Input Error1 is the minimumThe predecessor of 20 is 15The predecessor of 23 is 20The predecessor of 15 is 9Input Error1,5,30,35,end of printThe 3_th element is 30The 4_th element is 35The rank of 30 is 3_thThe rank of 35 is 4_thend of this test
#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include<algorithm>#include<math.h>#include<vector>#include<map>#include<string>using namespace std;#define nn 200005#define inf 0x7ffffstruct treap{    int sz,key,fix,num;    treap *ch[2];    treap(int key)    {        sz=1;        num=1;        fix=rand();        this->key=key;        ch[0]=ch[1]=0;    }    int compare(int x) const    {        if(x==key) return -1;        return x<key?0:1;    }    void maintain()    {        sz=num;        if(ch[0]!=0) sz+=ch[0]->sz;        if(ch[1]!=0) sz+=ch[1]->sz;    }};treap* root;void rotate(treap* &t,int d)//旋转{    treap *k=t->ch[d^1];    t->ch[d^1]=k->ch[d];    k->ch[d]=t;    t->maintain();    k->maintain();    t=k;}void insert(treap* &t,int x)//添加{    if(t==0) t=new treap(x);    else    {        int d=x<t->key?0:1;        insert(t->ch[d],x);        if(t->ch[d]->fix>t->fix)            rotate(t,d^1);    }    t->maintain();}void Delete(treap* &t,int x)//删除{    int d=t->compare(x);    if(d==-1)    {        treap *tmp=t;        if(t->ch[0]==0)        {            t=t->ch[1];            delete tmp;            tmp=0;        }        else if(t->ch[1]==0)        {            t=t->ch[0];            delete tmp;            tmp=0;        }        else        {            int k=t->ch[0]->fix>t->ch[1]->fix?1:0;            rotate(t,k);            Delete(t->ch[k],x);        }    }    else Delete(t->ch[d],x);    if(t!=0) t->maintain();}bool Find(treap *t,int x)//查找{    while(t!=0)    {        int d=t->compare(x);        if(d==-1) return true;        t=t->ch[d];    }    return false;}int kth(treap *t,int k)//找第K小的元素{    if(t==0||k<=0||k>t->sz)        return -1;    if(t->ch[0]==0&&k==1)        return t->key;    if(t->ch[0]==0)        return kth(t->ch[1],k-1);    if(t->ch[0]->sz>=k)        return kth(t->ch[0],k);    if(t->ch[0]->sz+1==k)        return t->key;    return kth(t->ch[1],k-1-t->ch[0]->sz);}int Rank(int x) //x的排名是多少,从小到大排序{    int ans=0;    treap* p=root;    while(1)    {        if(p->key==x)        {            ans+=1+(p->ch[0]?p->ch[0]->sz:0);            break;        }        else if(x<p->key)            p=p->ch[0];        else        {            ans+=p->num+(p->ch[0]?p->ch[0]->sz:0);            p=p->ch[1];        }    }    return ans;}int depth(treap *t){    if(t==0) return -1;    int l=depth(t->ch[0]);    int r=depth(t->ch[1]);    return l<r?(r+1):(l+1);}void delettreap(treap* &t)//释放空间{    if(t==0) return;    if(t->ch[0]!=0) delettreap(t->ch[0]);    if(t->ch[1]!=0) delettreap(t->ch[1]);    delete t;    t=0;}void Print(treap *t)//打印树,从小到大{    if(t==0) return;    Print(t->ch[0]);    printf("%d,",t->key);    Print(t->ch[1]);}int pre(int x){    treap* p=root;    int ans=0;    bool fuck=0;    while(p)    {        if(p->key<x)        {            ans=p->key;            fuck=1;        }        p=p->ch[p->key<x];    }    if(fuck) return ans;    return inf;}int suc(int x){    treap* p=root;    int ans=0;    bool fuck=0;    while(p)    {        if(p->key>x)        {            ans=p->key;            fuck=1;        }        p=p->ch[p->key<=x];    }    if(fuck) return ans;    return inf;}int main(){    int n,m;    char op[30];    while(~scanf("%s",op))    {        if(strcmp(op,"-1")==0)            break;        if(op[0]=='e')        {            puts("end of this test");            delettreap(root);            continue;        }        if(op[0]=='p'&&op[2]=='i')        {            Print(root);            puts("end of print");        }        else        {            int x;            scanf("%d",&x);            if(op[0]=='i')            {                if(!Find(root,x))                    insert(root,x);            }            else if(op[0]=='d')            {                if(Find(root,x))                    Delete(root,x);                else printf("Input Error\n");            }            else if(op[0]=='p'&&op[2]=='e')            {                if(Find(root,x))                {                    int y=pre(x);                    if(y<inf) printf("The predecessor of %d is %d\n",x,y);                    else printf("%d is the minimum\n",x);                }                else                    printf("Input Error\n");            }            else if(op[0]=='s')            {                if(Find(root,x))                {                    int y=suc(x);                    if(y<inf) printf("The successor of %d is %d\n",x,y);                    else printf("%d is the maximum\n",x);                }                else                    printf("Input Error\n");            }            else if(op[0]=='K')            {                int y=kth(root,x);                if(y==-1) printf("Input Error\n");                else printf("The %d_th element is %d\n",x,y);            }            else if(op[0]=='r')            {                if(!Find(root,x))                    printf("Input Error\n");                else printf("The rank of %d is %d_th\n",x,Rank(x));            }        }    }    return 0;}

0 0
原创粉丝点击