TREAP平衡树代码

/*
Author:Cnyali
*/
#include<stdio.h>
#include<stdlib.h>
#include <time.h> 
struct point{                    //结点结构 ;
    long key,first;              //key为权值,first为优先值; 
    struct point *lc,*rc,*fa;    //左儿子结点,右儿子结点,父亲结点; 
};
struct point *p,*head;
long i,j,k,m,n;
int treapw(struct point *s){     //中序遍历打印二叉树 
    if(s->lc!=NULL)
        treapw(s->lc);
    printf("%ld ",s->key);
    if(s->rc!=NULL)    
        treapw(s->rc);
    return 0;
}
int treapin(struct point *h,struct point *x){    //插入新结点到二叉树 
    if(x->key>h->key){
        if(h->rc==NULL){
            h->rc=x;x->fa=h;
            return 0;
        }
        treapin(h->rc,x);
    }else{
        if(h->lc==NULL){
            h->lc=x;x->fa=h;
            return 0;
        }          
        treapin(h->lc,x);
    }        
    return 0;
}
int rroute(struct point *x){    //右旋 
    struct point *y;
    y=x->fa;
    if(y==head)
        head=x;
    y->lc=x->rc;
    if(x->rc!=NULL)
        x->rc->fa=y;

    x->fa=y->fa;
    if(y->fa!=NULL){
        if(y->fa->lc==y)
            y->fa->lc=x;
        else
            y->fa->rc=x;    
    }
    y->fa=x;
    x->rc=y;        
    return 0;     
} 
int lroute(struct point *x){    //左旋 
    struct point *y;
    y=x->fa;
    if(y==head)
        head=x;    
    y->rc=x->lc;
    if(x->lc!=NULL)
        x->lc->fa=y;
    x->fa=y->fa;
    if(y->fa!=NULL){
        if(y->fa->lc==y)
            y->fa->lc=x;
        else
            y->fa->rc=x;    
    }
    y->fa=x;
    x->lc=y;        
    return 0;               
}
void prepare(){                          //准备及建立BST 
    srand( (unsigned)time(NULL) ); 
    scanf("%ld",&n);            
    p=(struct point *)malloc(sizeof(struct point));
    scanf("%ld",&p->key);
    p->lc=NULL;p->rc=NULL;p->fa=NULL;p->first=rand();
    head=p;
    for(i=2;i<=n;i++){
        p=(struct point *)malloc(sizeof(struct point));
        scanf("%ld",&p->key);
        p->lc=NULL;p->rc=NULL;p->fa=NULL;p->first=rand();    
        treapin(head,p);      
        if(p->fa!=NULL)
            while(p->first<p->fa->first){
                if(p->fa->lc==p)
                    rroute(p);
                else
                    lroute(p);
                if(p->fa==NULL)
                     break;                
            }
    }
    treapw(head);
    printf("\n");
}
struct point *treaps(struct point *h,long x){   //查询二叉树 
    if(h->key==x){
        return h;
    }
    if(h->key>x && h->lc!=NULL)
        return treaps(h->lc,x);
    else if(h->key<=x && h->rc!=NULL)
        return treaps(h->rc,x);   
    return NULL;       
}
struct point *minc(struct point *x){       //找到P的最小子结点 
    if(x->rc==NULL)
        return x->lc;
    else if(x->lc==NULL)
        return x->rc;
    else{
        if(x->lc->first>x->rc->first)
            return x->rc;
        else
            return x->lc;
    } 
    return NULL;       
}
void work(){                          //删除BST结点;
    scanf("%ld",&m);     
    for(i=1;i<=m;i++){
         scanf("%ld",&k);   
         p=treaps(head,k);
         if(p!=NULL){
             p->first=100000;
             if(p->lc==NULL && p->rc==NULL){  //叶子结点直接释放; 
                 if(p->fa!=NULL)
                     if(p->fa->lc==p)
                         p->fa->lc=NULL;
                     else
                         p->fa->rc=NULL;
                 free(p);
             }else{                           //堆调整 
                 while(p->first>minc(p)->first){
                     if(p->lc==minc(p))
                         rroute(p->lc);
                     else
                         lroute(p->rc);
                     if(p->lc==NULL && p->rc==NULL)
                         break;                                                  
                 }
                 if(p->fa!=NULL)
                     if(p->fa->lc==p)
                         p->fa->lc=NULL;
                     else
                         p->fa->rc=NULL;
                 free(p);                                                                 
             }                 
         }
         treapw(head);
         printf("\n");           
    }
}
int main(){
    freopen("treap.in","r",stdin);
    freopen("treap.out","w",stdout);
        prepare();
        work();
    return 0;
}

posted @ 2014-08-22 16:55  cnyali  阅读(112)  评论(0编辑  收藏  举报