haoningabc 发表于 2013-1-26 12:31:50

二叉树

转http://www.cnblogs.com/fornever/archive/2011/11/15/2249492.html
一句话,出来混,早晚是要还的,天天弄java,mlgbd基础全忘光了
#include <stdio.h>#include <stdlib.h>#include <string.h>typedef int Elemtype;typedef struct Balanced_Binary_Tree{    Elemtype e;    int bf;    struct Balanced_Binary_Tree *child;}*AVL;///------------简单的位操作-------------------void setbit(char *i,char val,char pos){    if(pos==1)      (*i)=(*i)|1;    else    {      if(val==1)    (*i)=(*i)|2;      else    (*i)=(*i)&1;    }}char getbit(char i,char pos){    ///调试时,发现这里能返回2/////    return (i&pos); 出错的地方    return (i&pos)&&1;    /////////////////////////////}///--------------------------------------------///-----------生成一个结点---------------------AVL createnode(Elemtype e){    AVL node=NULL;    node=(AVL)malloc(sizeof(struct Balanced_Binary_Tree));    node->e=e;    node->bf=0;    node->child=node->child=NULL;      return node;}///---------------------------------------------///★★★★★★★★AVL的核心操作★★★★★★★★★★★★///★★★★★★★★★保持平衡★★★★★★★★★★★★★★//改变因子函数void setfactor(AVL f,int button){    char fir=button/10,sec=button%10;    AVL s=f->child,ss=s->child;    char choice=ss->bf;    int a=1,b=0;    //////////调试时发现,删除时的特殊情况//////////////////插入时,不会有这种情况,若button=0,则s->bf=1///////若button=11,则s->bf=-1;然而删除时,却会出现//////button=0或者button=11时 s->bf=0!!!!!!!/////////////那么这种特殊情况,平衡后所得的因子就跟一般的///////不一样了!!!如下///////////////////////////////    if(button==0 && s->bf==0)    f->bf=1,s->bf=-1;    else if(button==11 && s->bf==0)    f->bf=-1,s->bf=1;    ///////////////////////////////////////////////////    else if(button==0 || button==11)    {      f->bf=0;      s->bf=0;    }    else    {      /////写博客时,发现这里有问题///////////////////    //    if(button==1)    choice=-choice;      /////但是为什么我测试的时候怎么都对?!////////////////经再次测试,上边确实错了!!!/////////////////////改为下边应该就对了吧///////////////////////      if(button==1)    {a^=b,b^=a,a^=b;}      ////////////////////////////////////////////////      if(choice==-1)    f->bf=a,s->bf=b;      else if(choice==0)    f->bf=s->bf=0;      else    f->bf=-b,s->bf=-a;                ss->bf=0;    }}//两节点变换函数void conversion(AVL *T,char direction){    AVL f=*T,s=f->child;    f->child=s->child[!direction];    s->child[!direction]=f;    *T=s;}//保持平衡函数void keepbalance(AVL *T,char fir,char sec){    AVL *s=&((*T)->child);    int button=fir*10+sec;    if(button==0 || button==11)    {      setfactor((*T),button);      conversion(T,fir);    }    else    {      setfactor((*T),button);      conversion(s,sec);      conversion(T,fir);    }}///★★★★★★★★★★★★★★★★★★★★★★★★★★///------------插入时的选向操作-------------------void selectforInsert(AVL *T,char *info,int direction){    AVL cur=*T;    char firdirection,secdirection;    if(direction==0)    (cur->bf)++;    else    (cur->bf)--;    if(cur->bf==0)    setbit(info,1,1);    else if(cur->bf==-1 || cur->bf==1)    setbit(info,direction,2);    else    {                firdirection=direction;      secdirection=getbit(*info,2);      keepbalance(T,firdirection,secdirection);      setbit(info,1,1);    }}//----------------------------------------------//*************插入操作************************//char InsertAVL(AVL *T,Elemtype e){                              //可用于查询    char info;      if(!(*T))    {      (*T)=createnode(e);      return 0;    }    else if((*T)->e==e)      return -1;    else if((*T)->e>e)//左    {      info=InsertAVL(&((*T)->child),e);      if(getbit(info,1))    return info;                selectforInsert(T,&info,0);    }    else            //右    {      info=InsertAVL(&((*T)->child),e);      if(getbit(info,1))    return info;      selectforInsert(T,&info,1);    }    return info;}//*********************************************////-------------删除时的选向操作--------------------void selectforDelete(AVL *T,char *info,char direction){    AVL cur=(*T);    char firdirection,secdirection;    if(direction==0)    (cur->bf)--;    else    (cur->bf)++;      if(cur->bf==0)    *info=0;    else if(cur->bf==-1 || cur->bf==1)    *info=1;    else    {      firdirection=!direction;      ///调试时,发现这里少写了一个等号//////////////////////      if(cur->child->bf=1)    secdirection=0;草,真帅气!原来1==a这样写确实有必要!      if(1==cur->child->bf)    secdirection=0;      /////////////////////////////////////////////////////      else    secdirection=1;      keepbalance(T,firdirection,secdirection);      ////////////////////////////////////////////////////////////////////////////////////////////调试时,发现经过子树平衡操作后,*info不一定都是0,就是那个特殊情况,在setfactor中////////的那种特殊情况时,这里*info应改为1! 所以代码改如下:///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    //    *info=1; 写代码时:这跟插入可不一样啊...该子树平衡了,它父节点的因子比变!//    *info=0;//因此,这还没完还要是0!! ............啊……这里不一定是0! ////还是那个特殊情况搞的鬼!//      if(cur->bf==0)    *info=0;      else    *info=1;      /////////////////////////////////////////////////////////////////////////////////////////    }}//------------------------------------------------//-------------变向递归--辅助删点-----------------char find(AVL *gogal,AVL *p){    char info;    AVL tp=NULL;      if(NULL!=(*p)->child)    {      info=find(gogal,&((*p)->child));      if(info!=0)    return info;      selectforDelete(p,&info,0);    }    else    {      (*gogal)->e=(*p)->e;      tp=(*p)->child;      free((*p));      *p=tp;      info=0;    }    return info;}//------------------------------------------------//**************删除操作*************************//char DeleteAVL(AVL *T,Elemtype e){    char info;    AVL tp=NULL;    if(!(*T))    return -1;//原if(!T)    return -1;于2011年11月29日8:59:15修改    else if((*T)->e==e)    {      if(NULL!=(*T)->child)      {            info=find(T,&((*T)->child));            if(info!=0)    return info;            selectforDelete(T,&info,1);      }      else      {            //////////////调试时,发现这样写不对!!!///////////////////////////////////////      //    (*T)=(p=(*T)->child)-(free((*T)),0);//Just save a variable! 这里出问题//    (*T)=p-(free((*T)),0); 可以//    (*T)=(p=((*T)->child))+(free((*T)),0); 不可以            tp=((*T)->child);            free((*T));            *T=tp;            //调试时,发现这里漏了给info赋值            info=0;            ///////////////////////////////////////////////////////////////////////////////      }    }    else if((*T)->e>e)    {      info=DeleteAVL(&(*T)->child,e);      if(info!=0)    return info;      selectforDelete(T,&info,0);    }    else    {      info=DeleteAVL(&(*T)->child,e);      if(info!=0)    return info;      selectforDelete(T,&info,1);    }    return info;}//************************************************////*****************JUST FOR TEST************************//#define MOVE(x)    (x=(x+1)%1000)AVL queue;void print(AVL p,int i){    int front,rear,temp,count;    front=rear=-1; count=temp=0;    queue=p; count++;      printf("%d\n",i);    while(front!=rear)    {      p=queue;    count--;                        if(p->child)    queue=p->child,temp++;      if(p->child)    queue=p->child,temp++;                printf("%d->%d ",p->e,p->bf);      if(count==0)      {            printf("\n");            count=temp;            temp=0;      }      }    printf("\n");}//**************************************************//int main(){    AVL T=NULL;    int i,nodenum=0;    freopen("input.txt","w",stdout);    nodenum=100;    for(i=0;i<nodenum;i++)    {      InsertAVL(&T,i);    }      print(T,-1);    for(i=0;i<nodenum-1;i++)    {      DeleteAVL(&T,i);      print(T,i);    }      return 0;}
页: [1]
查看完整版本: 二叉树