二叉樹的簡單C實現

#include<stdio.h>
#include<stdlib.h>
typedef struct TNode{
  char data;
  struct TNode *lchild,*rchild;
}TNode,*Tree;
//初始化二叉樹
Tree create_tree(void){
  Tree T;
  char ch;
  scanf("%c",&ch);
  if(ch=='#')
     T=NULL;
    else { 
      if(!(T=(TNode*)malloc(sizeof(TNode))))
            exit(-2);
            T->data=ch;
            T->lchild=create_tree();
            T->rchild=create_tree();
        }
        return T;
}
//先序遍歷二叉樹--遞歸調用
void preorder_traverse(TNode* T){

 Tree p=T;
   if(NULL!=p){
   printf(" %c",p->data);
   preorder_traverse(p->lchild);
    preorder_traverse(p->rchild);

 }
}
//中序遍歷二叉樹 --遞歸調用
void inorder_traverse(Tree T){
 Tree p=T;
  if(NULL!=p){
       inorder_traverse(p->lchild);
    printf("  %c",p->data);
    inorder_traverse(p->lchild);
 }
}
//後序遍歷二叉樹 --遞歸調用
void  postorder_traverse(Tree T){
  Tree p=T;
   if(NULL!=p){
   postorder_traverse(p->lchild);
   postorder_traverse(p->rchild);
   printf("  %c",p->data);
 
  }
}
//葉子節點的個數
int leaf(Tree T){
 Tree p=T;
 if(NULL!=p){
  if(( NULL==p->lchild) && (NULL==p->rchild))
 { 
       return 1;
    }
  else
   return (leaf(p->lchild)+leaf(p->rchild));
 }else
  return 0;
}
//節點的總個數
int counter(TNode *t)
{int s;
if(NULL==t) return(0);
else s=counter(t->lchild)+counter(t->rchild)+1;
return(s);
}

//樹的深度
int depth(Tree T){
 Tree p=T;
 int l,r;
 if(NULL!=p){
  l=depth(p->lchild);
  r=depth(p->rchild);
  if(l>r)
   return l+1;
  else
   return r+1;
 
 }else{
  
   return 0;
 }
}
//交換節點
void change_node(Tree T){
  Tree p=T;
  if(NULL!=p){
    p=T->lchild;
 T->lchild=T->rchild;
 T->rchild=p;
 change_node(T->lchild);
 change_node(T->rchild);
  }
}
//查找節點
Tree find_node(Tree t,char x){
Tree p;
if(!t) return(NULL);
else if(t->data==x)return (t);
else{
p=find_node(t->lchild,x);
if(!p)p=find_node(t->rchild,x);
return(p);
}
}

//層序遍歷二叉樹  用到隊列的思想
void layer_traverse(Tree t){
Tree T;
char q[20];//類似於隊
int i=-1,j=-1;//i模擬隊列的尾節點,j模擬隊列的頭節點
T=t;
if(T!=NULL) {i++; q[i]=T->data;}
while(j<i){
j++;//頭節點出隊
T=find_node(t,q[j]);
if(NULL!=T->lchild) {i++; q[i]=T->lchild->data;}
if(NULL!=T->rchild) {i++;q[i]=T->rchild->data;}
}
for(j=0;j<=i;j++)printf("%c",q[j]);
}
//查找父節點..t:要查找的樹 q:要查找的節點
Tree find_parent(TNode *t,TNode *q)
{TNode *p,*s;
if(NULL==t) s=NULL;
else if(t->lchild==q || t->rchild==q) s=t;
else {p=find_parent(t->lchild,q);
if(NULL==p) p=find_parent(t->rchild,q);
s=p;
}
return(s);
}

void show_menu(){
printf("\t\t\t****二叉樹簡單算法****\n");
printf("\t\t\t~~~~~~~~~~~~~~~~~~~~~\n");
printf("\t\t\t#1. 先序遍歷 #\n");
printf("\t\t\t#2. 中序遍歷 #\n");
printf("\t\t\t#3. 後序遍歷 #\n");
printf("\t\t\t#4. 層序遍歷 #\n");
printf("\t\t\t#5. 節點個數 #\n");
printf("\t\t\t#6. 二叉樹深度 #\n");
printf("\t\t\t#7. 節點交換 #\n");
printf("\t\t\t#8. 查找出某結點的父結點 #\n");
printf("\t\t\t#9. 求二叉樹的高度 #\n");
printf("\t\t\t#0. 退出程序 #\n");
}
int main(int argc, char* argv[])
{   
 int a;
 Tree T,p,q;
 int t,l,d,h,m,i;
 char ch;
 printf("\t\t\t***創建二叉樹****\n");
 printf("請輸入樹的各元素,用#表示空節點\n");
 T=create_tree();
 while(1){
  show_menu();
  printf("請您選擇(0-6):");
  scanf("%d",&t);
  switch(t){
  case 1:
      printf("◎先序遍歷:");
   preorder_traverse(T);
   printf("\n");
   break;

  case 2:
      printf("◎中序遍歷:");
   inorder_traverse(T);
   printf("\n");
   break;
 
  case 3:
      printf("◎後序遍歷:");
   postorder_traverse(T);
   printf("\n");
   break;
  
    case 4:
  printf("◎層序遍歷:");
   layer_traverse(T);
   printf("\n");
   break;
    case 5:
   printf("  ◎結點個數:\n");
  l= leaf(T);
  printf("   葉子節點:%d\n ",l);
  i=counter(T);
     printf("   總共節點:%d",i);
   break;

    case 6:
   printf("  ◎二叉樹深度:");
   d=depth(T);
   printf("  %d\n",t);
   break;

      case 7:
  printf("   各結點已交換");
  change_node(T);
  printf("%d\n",t);
  break; 
    case 8:
    printf("    查找出某結點的父結點\n");
       printf("    請輸入結點數值(該數值爲您已經建立的二叉樹中除根結點以外的):\n");
       scanf("    %s",&ch);
       q=find_node(T,ch);
       p=find_parent(T,q);
      if(p!=NULL){
    printf("    結點的父結點值爲:\n");
       printf("%c\n\n",p->data);
   } else
       printf("    該結點無父結點\n");
  break; 
 case 9:
          h=depth(T);
      printf("     該二叉樹的高度爲:%d\n\n",h);
     break;

       case 0:
      printf("\t\t******88!******\n");
     return 0;
     break;
       default:
     printf("      ※輸入出錯!!!請重輸:\n");


 
  }
 }

scanf("%d",&a);
return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章