/*
* 程序的版权和版本声明部分:
* Copyright (c) 2013,郑州大学SIAS国际学院
* 作 者: 王 杰
* 完成日期:2013 年 12 月 12 日
*
* 对任务及求解方法的描述部分:
* 输入描述: 略或见注释、总结
* 问题描述: 略或见注释、总结
* 程序输出: 略或见注释、总结
* 问题分析: 略或见注释、总结
* 算法设计: 略或见注释、总结
*/
/*
二叉树子系统---构造函数
1建二叉树 2先序遍历(递归)
3中序遍历(递归) 4后序遍历(递归)
5层次遍历(借助队列) 6求叶子数(递归)
7求节点数(递归) 8求树深度(递归)
0返回
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct BT{
char data;
BT *lchild;
BT *rchild;
}BT;
int count=0; //全局变量。。。
//1建二叉树
BT *createtree()
{
BT *bt;
char x;
scanf("%c",&x);
getchar(); //处理回车键
if(x=='0')
bt=NULL;
else{
bt=(BT*)malloc(sizeof(BT));
bt->data=x;
printf("请输入%c节点的左子结点\n",bt->data); //最好有提示,不然你会在建树.......
bt->lchild=createtree();
printf("请输入%c节点的右子结点\n",bt->data);
bt->rchild=createtree();
}
return bt;
}
//2先序遍历
void preorder(BT *T)
{
if(T==NULL) return;
{
printf("%c ",T->data);
preorder(T->lchild);
preorder(T->rchild);
}
}
//3中序遍历
void inorder(BT *T)
{
if(T==NULL) return;
{
inorder(T->lchild);
printf("%c ",T->data);
inorder(T->rchild);
}
}
//4后序遍历
void postorder(BT *T)
{
if(T==NULL) return;
{
postorder(T->lchild);
postorder(T->rchild);
printf("%c ",T->data);
}
}
//5层次遍历
void levelorder(BT *T)
{
int i,j;
BT *q[100],*p; //定义一个指针数组
p=T;
if(p!=NULL){
i=1;
q[i]=p;
j=2;
}
while(i!=j){
p=q[i];
printf("%c ",p->data);
if(p->lchild!=NULL){
q[j]=p->lchild;
j++;
}
if(p->rchild!=NULL){
q[j]=p->rchild;
j++;
}
i++;
}
}
//6求叶子数
int leafnum(BT *T)
{
if(!T)
return 0;
else{
if(T->lchild==NULL && T->rchild==NULL)
count++;
leafnum(T->lchild);
leafnum(T->rchild);
return count;
}
}
/*
//其实6/7函数也可以定义成void型,因为count是全局变量,调用函数可以直接在count上改变count的值,然后输出count就OK
void leafnum(BT *T)
{
if(!T)
; //什么也不做
else{
if(T->lchild==NULL && T->rchild==NULL)
count++;
leafnum(T->lchild);
leafnum(T->rchild);
}
}
*/
//7求节点数
int nodenum(BT *T)
{
if(!T)
return 0;
else{
count++;
nodenum(T->lchild);
nodenum(T->rchild);
return count;
}
}
//8求树深度
int treedepth(BT *T)
{
int ldep,rdep,dep;
if(T==NULL)
return 0;
else{
ldep=treedepth(T->lchild);
rdep=treedepth(T->rchild);
dep=ldep>rdep?ldep:rdep;
return dep+1;
}
}
int main()
{
BT * bt;
int choice;
int j=1;
while(j){
printf(" 二叉树子系统 \n");
printf("*******************************************************\n");
printf(" 1-------建二叉树 \n");
printf(" 2-------先序遍历 \n");
printf(" 3-------中序遍历 \n");
printf(" 4-------后序遍历 \n");
printf(" 5-------层次遍历 \n");
printf(" 6-------求叶子数 \n");
printf(" 7-------求节点数 \n");
printf(" 8-------求树深度 \n");
printf(" 0-------返 回 \n");
printf("*******************************************************\n");
printf(" 请输出想要输入的数字: ");
scanf("%d",&choice);
getchar(); //处理回车键
switch(choice){
case 1:
printf("请按先序序列输入二叉树的节点。说明:输入节点(‘0’表示后继节点为空)后按回车\n"); //提示不可少
printf("请输入根节点:");
bt=createtree();
printf("二叉树成功建立!\n");break;
case 2:
printf("该二叉树的先序遍历序列为:");
preorder(bt);
printf("\n");break;
case 3:
printf("该二叉树的中序遍历序列为:");
inorder(bt);
printf("\n");break;
case 4:
printf("该二叉树的后序遍历序列为:");
postorder(bt);
printf("\n");break;
case 5:
printf("该二叉树的层次遍历序列为:");
levelorder(bt);
printf("\n");break;
case 6:
count=0; //初始化count值,因为count是全局变量,避免计算叶子节点和节点时,count值累加
//count=leafnum(bt);
printf("该二叉树有%d个叶子\n",leafnum(bt));break;
//开始的时候一直以为没有把地址给传过去,实际上已经传过去了if(T)变成if(!T)
/*
函数为void时:
case 6:
leafnum(bt);
printf("该二叉树有%d个叶子\n",count);break;
//调用leafnum()函数后,直接在count上进行操作,所以count可以直接输出,
这就是全局变量的好处,直接对内存进行操作,有点像指针
*/
case 7:
count=0;
//count=nodenum(bt);
printf("该二叉树总共有%d个节点\n",nodenum(bt));break;
case 8:printf("该二叉树的深度是%d:\n",treedepth(bt));break;
case 0:j=0;break;
}
}
return 0;
}
心得:有关全局变量的,见注释;还有最重要的就是递归!!;还有就是借助队列,等等等等