二叉排序树操作及其树形

来源:互联网 发布:淘宝店铺二级域名收费 编辑:程序博客网 时间:2024/06/05 00:42

在做二叉树的操作树的形状很难直观的表现,在本代码里将有较好的视觉体验





不多说代码如下:

#include<stdio.h>  #include<stdlib.h> typedef struct tree{    int data;    struct tree *lchild,*rchild;}TREE,*Bitree;Bitree createTree(int *arr,int len);//根据用户输入的数组arr[],采用排序二叉树构建二叉树,返回树的根void bianli(Bitree p,int a);//a=1时中序遍历,a=2时销毁树Bitree search(Bitree p,int key);  //主函数调用后,查找元素key返回指向该元素节点p,当p=null时查找无果int insert(Bitree &pir,int key);//主函数调用后 插入key值,成功返回1失败返回0,函数内部配合函数findpir,int findpir(Bitree pir,int key,Bitree parent,Bitree &p);//无需在主函数调用,嵌套在insert里,用于在pir指向的子树查找int deletekey(Bitree &p,int key);//删除指向key的指针,如果成功返回1并配合deletesearch(Bitree &p)失败返回0,void deletesearch(Bitree &p);//无需在主函数调用,嵌套在deletekey里,删除p指向的值,void shu(Bitree &p,int len);//输出树的形状,形参len=0;void tiaozheng(int a);//根据位数调整枝杈长度,嵌套在shu函数里void main(){    int i,num,yuan,*a=NULL;    Bitree p=NULL;char biao[][5]={"查找","插入","删除"},xuan[][5]={"失败","成功"};do{printf("输入的数据个数(2-2000):");scanf("%d",&num);while(getchar()!='\n');}while(num<2||num>2000);a=(int *)malloc(num*sizeof(int));if(!a)  exit(0);printf("注:输入元素相同时,将只保留一个,元素数值范围(0-99999):\n");for(i=0;i<num;i++)do{printf("请输入第%d个元素:",i+1);scanf("%d",a+i);while(getchar()!='\n');if(*(a+i)<0||*(a+i)>99999)printf("输入有误,");}while(*(a+i)<0||*(a+i)>99999);p=createTree(a,num);           //调用函数建立排序树do{system("cls");printf("①--②--③--④--⑤--⑥--⑦--⑧--⑨--⑩--①--②--③--④--⑤--⑥--⑦--⑧--⑨--⑩\n");shu(p,0);printf("1:中序遍历输出\n2:查找元素\n3:插入元素\n4:删除元素\n5:销毁树+退出:\n");do{printf("请输入你的选择:");scanf("%d",&num);                //选择while(getchar()!='\n');}while(num<1||num>5);if(num==1||num==5)bianli(p,num==1?1:2);                    //遍历树else {do{printf("输入%s的元素(0-99999)",biao[num-2]);     //插入或删除还有查找的数记录在yuan里scanf("%d",&yuan);while(getchar()!='\n');}while(yuan<0||yuan>99999);printf("%s",biao[num-2]);yuan=(num==3&&insert(p,yuan)||num==2&&search(p,yuan)||num==4&&deletekey(p,yuan));printf("%s!\n",xuan[yuan]);}system("pause");}while(num!=5);}Bitree createTree(int *arr,int len)//根据用户输入的数组arr[],采用排序二叉树构建二叉树  {      Bitree p=NULL;      int i;       for(i=0;i<len;i++)          insert(p,arr[i]);      return p;     }Bitree search(Bitree p,int key)  //递归查找元素key返回指向该元素节点p,当p=null时查找无果{      if(!p|| p->data == key) //优先判断:查找到时返回指向该元素节点p,没查找到时p为NULL          return p;      else if(key < p->data)            //如果key小于当前节点的值,则在其左子树中查找          return search(p->lchild,key);      else                                //否则在其右子树中查找          return search(p->rchild,key);  }int insert(Bitree &pir,int key)//key值接入树中,插入成功返回1失败返回0  {      Bitree p;      if(!findpir(pir,key,NULL,p))        //如果查找到key值是原来的树中没有的,则执行插入操作      {                                  //经 findpir函数后p保存了插入的位置的父节点 ,为新节点分配空间,并将key赋值给新节点          Bitree New= (Bitree)malloc(sizeof(TREE)); if(!New)   exit(0);        New->data = key;          New->lchild = New->rchild = NULL;          if(!p)                          //如果树空,则直接将New为根节点              pir=New;          else if(key<p->data)            //作为左孩子插入p的左边              p->lchild=New;                   else              p->rchild=New;          return 1;      }      else          return 0;  } //在pir所指的二叉树中查找key,成功返回1,将p指向key,失败返回0,p保存查找失败的接点的父节点(父节点parent初始化为NULL)int findpir(Bitree pir,int key,Bitree parent,Bitree &p)  {      if(!pir)         //如果pir为NULL,则查找不成功                                                      {         p = parent;          return 0;      }      else             //否则,继续查找      {                                         if(key==pir->data)           //如果相等,则查找成功                              {              p = pir;              return 1;          }          else if(key<pir->data)        //在左子树中递归查找              return findpir(pir->lchild,key,pir,p);    //pir在第k层递归中已经记录了当前节点,当作k+1层父节点        else                            //在右子树中递归查找              return findpir(pir->rchild,key,pir,p);    }  } int deletekey(Bitree &p,int key)  {       if(!p)            //不存在关键字为key的节点         return 0;      else      {             if(key == p->data)       //查找到关键字为key的节点          {    deletesearch(p);    //调用函数deletesearch(p)            return 1;                      }          else if(key < p->data)  //继续查找左子树              return deletekey(p->lchild,key);          else                        //继续查找右子树              return deletekey(p->rchild,key);      }  } void deletesearch(Bitree &p) //删除p指向的值 {       Bitree q,s;      if(!p->lchild)         {              //如果左子树为空,则只需重接其右子树          q = p;      //q暂时存p的值        p = p->rchild ;//p连接右子树          free(q);  //释放q    }      else if(!p->rchild)      {   //如果右子树为空,则只需重接其左子树          q = p;          p = p->lchild;          free(q);      }      else      {   //如果左右子树都不为空,重接左右子树,中序遍历就是一竖排一竖排的读,左边一定小于右边            s = p->lchild;       //取待删节点的左节点,左节点比待删节点小             while(s->rchild)   //一直向右(右边比待删节点大),最终末节点s为待删节点的右接点父(前驱)节点              s = s->rchild;          s->rchild = p->rchild;    //将p的右子树接到s的右边          q = p;         //      //需要把待删节点的左节点 连接在 待删除节点的位置        p = p->lchild;       //将p的左子树接到p的父节点的左子树上          free(q);      }  } void bianli(Bitree p,int a)//a=1时中序遍历a=2时销毁树 {      if(p)      {          if(p->lchild)              bianli(p->lchild,a);if(a==1)printf("%-6d",p->data);          if(p->rchild)              bianli(p->rchild,a); if(a==2){free(p);p=NULL;//跳出循环}    }  }void shu(Bitree &p,int len)//数的形状len=0;{int i;if (p!=NULL){shu(p->rchild,len+1);for (i=1;i<=4*len;i++){if(i%4==1)printf("|");elseprintf(" ");}printf("%d",p->data);tiaozheng(p->data);shu(p->lchild,len+1);}}void tiaozheng(int a){char cha[6][7]={">--+<",">--+<",">-+<",">+<","><","<"};int k=0;while(a){ a/=10;      k++;}printf("%s\n",cha[k]);}


3 0
原创粉丝点击