二叉树的简单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;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值