回 帖 发 新 帖 刷新版面

主题:二叉树各种操作算法

#include"stdlib.h"    /* 存储分配头文件,或用"malloc.h" */
#include"stdio.h"     /* 标准I/O头文件 */
#include"ctype.h"  
#define N 10000                     /* 定义NULL,本行可省去 */
#define LENG sizeof(struct Bnode)  /* 确定结点所占空间的字节数 */
typedef char ElemType;            /* 抽象元素类型为char类型 */


typedef struct Bnode              /* Bnode为结点(C结构体)类型 */
{ ElemType data;                 /* data为抽象元素类型 */
   struct Bnode *lchild, *rchild; /* 为指针类型  */
   signed size;
}Bnode;
int node[4] ;
int creat_tree(Bnode**root )   /* root是指向指针的指针类型 */
{ /* 本算法递归生成二叉树 */
      ElemType ch;
      scanf("%c",&ch);                                       /* 输入结点,字符型 */
      if (ch==' '){ (*root)->data=NULL;
                            return;}                       /* 生成空二叉树 */
      else                                                              /* 生成非空二叉树 */
       { (*root)=(Bnode*)malloc(LENG);       /* 申请结点空间 */
     (*root)->data=ch;                       /* 生成根结点 */
     creat_tree(&(*root)->lchild); /* 递归生成左子树 */
     creat_tree(&(*root)->rchild);    /* 递归生成右子树 */
        }
} /* creat_tree */

void preorder1(Bnode *root)
{                                                    /* 前序遍历二叉树 */
   if (root)
  {    printf("%c",root->data);
     if(root->lchild)preorder1(root->lchild);
     if(root->rchild)preorder1(root->rchild);
  }
} /* preorder */

void preorder2(Bnode *root)
{                                                    /* 中序遍历二叉树 */
    if (root)
    {
         if(root->lchild)preorder2(root->lchild);
         printf("%c",root->data);
        if(root->rchild)preorder2(root->rchild);
     }
} /* preorder */

void preorder3(Bnode *root)
{                                                    /* 后序遍历二叉树 */
        if (root)
       {
            if(root->lchild)preorder3(root->lchild);
            if(root->rchild)preorder3(root->rchild);
            printf("%c",root->data);
       }
} /* preorder */

void preorder4(Bnode *root)/*中序非递归遍历二叉树*/
{   Bnode  *p,*stack[N];
     int top=0;
      p=root;
do{
    while(p!=NULL)
    {
      top++;
      stack[top]=p;
      p=p->lchild;
    }
    if(top>0)
   {
     p=stack[top];/*p所指的 节点为无左子树或其左子树已经遍历过*/
      top--;
     printf("%c",p->data);
     p=p->rchild;
   }
}while(p!=NULL||top!=0);
} /* preorder */

void preorder5(Bnode *root)/*先序非递归遍历二叉树*/
{   Bnode  *p,*stack[N];
     int top ;
      p=root;
   if(root!=NULL)
        {top=1;
          stack[top]=p;
           while(top>0)
          {
           p=stack[top]  ;/*将右小孩放入栈*/
           top--;
           printf("%c",p->data);
           if(p->rchild!=NULL)
           {top++;
            stack[top]=p->rchild;
           }
            if(p->lchild!=NULL)
           {top++;
            stack[top]=p->lchild;
            }
}
} /* preorder */
void degrees(Bnode *root)/*中序非递归遍历二叉树*/
{   Bnode  *p,*stack[N];
     int top=0,i=0,j=0,k=0;
      p=root;
do{
    while(p!=NULL)
    {
      top++;
      stack[top]=p;
      p=p->lchild;
    }
    if(top>0)
   {
     p=stack[top];/*p所指的 节点为无左子树或其左子树已经遍历过*/
      top--;
      if(p->lchild!=NULL&&p->rchild!=NULL)k++;
     else  if(p->lchild==NULL&&p->rchild==NULL)i++;
      else j++;
     printf("%c",p->data);
     p=p->rchild;
   }
}while(p!=NULL||top!=0);
printf("Dgrees=0:   %d",i);
printf("Dgrees=1:    %d",j);
printf("Dgrees=2:   %d",k);
} /* preorder */

int  nodes(Bnode *root)
{
int num1,num2;
if(root==NULL)return(0);
else
{
  num1=nodes(root->lchild);
  num2=nodes(root->rchild);
  return(num1+num2+1);/*加1是因为要算上根节点*/
}
}
int  nodeO(Bnode *root)
{
int num1,num2;
if(root==NULL)return(0);
else
{
  num1=nodeO(root->lchild);
  num2=nodeO(root->rchild);
  if(root->lchild==NULL&&root->rchild==NULL)
  return(num1+num2+1);/*加1是因为要算上根节点*/
  else  return(num1+num2);
}
}

int  node1(Bnode *root)
{
int num1,num2;
if(root==NULL)return(0);
else if( (root->lchild!=NULL&&root->rchild==NULL) ||(root->lchild==NULL&&root->rchild!=NULL))
  return(1);
else
{
  num1=node1(root->lchild);
  num2=node1(root->rchild);
   return(num1+num2+1 );/*加1是因为要算上根节点*/
    
  }
}
int  node2(Bnode *root)
{
int num1,num2;
if(root==NULL)return(0);
else
{
  num1=node2(root->lchild);
  num2=node2(root->rchild);
  if(root->lchild!=NULL&&root->rchild!=NULL)
  return(num1+num2+1);/*加1是因为要算上根节点*/
  else  return(num1+num2);
}
}
void main(void)      /*主函数*/
    { int j ;
      char CH;  
      Bnode *root;  /* root是指向根结点的指针变量 */
      root=(Bnode *)malloc(sizeof(Bnode ));
do{
      printf("\n1:Create Tree:");
      printf("\n2:Travel Tree:(DLR)");
      printf("\n3:Travel Tree:(LDR)");
      printf("\n4:Travel Tree:(LRD)");
      printf("\n5:Travel Tree:(LDR)(FeiDiGui):");
      printf("\n6:Travel Tree:(DLR)(FeiDiGui):");
      printf("\n7:Degrees  of Tree:(DiGui);");
      printf("\n8:Degrees  of Tree:(FeiDiGui);");
      printf("\nChoose :");
      scanf("%d",&j);
      switch(j){
      case 1:creat_tree(&root);
      break;/* 取根指针变量的地址,生成二叉树 */
      case 2:preorder1(root);    break;   /* 前序遍历二叉树 */
      case 3:preorder2(root);    break;  /* 中序遍历二叉树 */
      case 4:preorder3(root);    break;  /* 后序遍历二叉树 */
      case 5:preorder4(root);    break;  /* 非递归中序遍历二叉树 */
      case 6:preorder5(root);    break;  /* 非递归先序遍历二叉树 */
      case 7:node[3] =nodes(root);
                   printf("SIZE OF TREE=%d",node[3] ) ;  /* 递归算法求节点总数*/
                   node[0] =nodeO(root);
                   printf("Degree=0:%d",node[0] ) ;
                   node[1] =node1(root);
                   printf("Degree=1:%d",node[1] ) ;
                   node[2] =node2(root);
                   printf("Degree=2:%d",node[2] ) ;break;
      case 8: degrees(root); break;
      default:printf("Choose from 1,2,3,4...8");break;
     }
printf("\nCONTINUE?(Y/N)");
while(isspace(CH=getchar()));
}while(CH!='N'||CH!='n');
printf("\nbyebye!");
}

[em16][em16][em16][em16]

回复列表 (共19个回复)

沙发

标准二叉树。问题应当说没有。但是提一个建议。在遍历的时候不要写上printf这类的话,应该调用一个方法,譬如说visit之类的。这样有通用性,以后访问节点如果不要printf要其它的那只要修改那个visit就可以了。

板凳

谢谢你的指教啊.

3 楼

万分改写楼主的帖子,我这几天正在为这事郁闷ing,解决了我的燃眉之急,在这里说一句"thank you!!!"
问楼主一个问题:
为什么根接点要用二维指针呢?不能用一维指针吗?请不吝赐教,谢谢

4 楼

我也是上学期学的数据结构,其实用一级指针也可以的,这个无所谓的!不过用二级指针规范些.这里我们是用一个指针指向树的根结点,用一级指针的话就是直接从树的跟出发,不知你能不能明白我的意思.

5 楼

有位朋友给我发了邮件,我看过了,你的程序中构造树的时候在遇到输入为空的时候需要一个return语句来返回上层。再就是你看看遍历是不是有点毛病。你可以参考我上面给出的算法。我这个主要参考数据结构清华版本的教材上的部分算法。写的还是比较规范的。

6 楼

反正看不懂

7 楼

有删除的算法吗?

8 楼

学习,备查

9 楼

我初步运行了一下,发现 "missing a }",可能是楼主粗心了点哦!
另外,如按照上述二叉树的创建函数 creat_tree(Bnode**root )
是无法实现的应该改换部分代码:
将代码:
  if (ch==' ')
       { (*root)->data=NULL;
                     return;}                       /* 生成空二叉树 */
改为:if(ch==' ')
      *root=NULL;
......
而最为重要的一点是 加上:
free(root);
注意内存泄漏哦!!!

10 楼

刚学2叉树  看完楼主的程序受益很大  谢谢  谢谢

我来回复

您尚未登录,请登录后再回复。点此登录或注册