题目:
二叉树的建立,遍历及其应用设树结点的元素类型为ElemType(可以为char或int),实现以下二叉树的各种基本操作的程序。
实验要求:
1.通过文件读取方式,建立不少于10个结点的二叉树T;
2.用非递归方式先序遍历方式输出树T的结点
3.用非递归方式中序遍历方式输出树T的结点
4.用后序遍历方式输出树T的结点
5.用层次遍历方式输出树T的结点
6.输出树T的深度
7.输出树T的叶子节点和非叶子结点
8.主函数通过函数调用实现以上各项操作
#include<stdio.h>
#define M 100
typedef struct BiTNode
{ char data;
struct BiTNode*lchild;
struct BiTNode*rchild;
}BiTNode,*BiTree;
BiTree create(BiTree T)
{ BiTree stack[M],p=NULL;
int top=-1,flag;
char ch;
FILE*fp;
if((fp=fopen("d.txt","r"))==NULL)
{ printf("can not open data file\n");
exit(0);
}
ch=fgetc(fp);
while(ch!=EOF)
{ switch(ch)
{ case'(':top++;stack[top]=p;flag=1;break;
case')': top--;break;
case',':flag=2;break;
default:p=(BiTree)malloc(sizeof(BiTNode));
p->data=ch;p->lchild=p->rchild=NULL;
if(T==NULL)
T=p;
else
{ switch(flag)
{ case 1:stack[top]->lchild=p;break;
case 2:stack[top]->rchild=p;break;
}
}
}
ch=fgetc(fp);
}
fclose(fp);
return T;
}
void preorder(BiTree T){
BiTree stack[M];
int top=-1;
BiTree p=T;
while(p!=NULL||top!=-1){
if(p!=NULL){
stack[++top]=p;
printf("%c",p->data);
p=p->lchild;
}else{
p=stack[top--];
p=p->rchild;
}
}
}
void inorder(BiTree T){
BiTree *stack[M];
int top=-1;
BiTree p=T;
while(p!=NULL||top!=-1){
if(p!=NULL){
stack[++top]=p;
p=p->lchild;
}else{
p=stack[top--];
printf("%c",p->data);
p=p->rchild;
}
}
}
void postorder(BiTree T)
{ if(T!=NULL)
{ postorder(T->lchild);
postorder(T->rchild);
printf("%c",T->data);
}
}
void levelorder(BiTree T){
BiTree queue[M];
int front=0;
int rear=0;
BiTree p=T;
queue[rear++]=p;
while(p!=NULL){
p=queue[front++];
printf("%c",p->data);
if(p->lchild){
queue[rear++]=p->lchild;
}
if(p->rchild){
queue[rear++]=p->rchild;
}
}
}
int LeafNum(BiTree T) {
if (!T) {
return 0;
} else if (!T->lchild && !T->rchild) {
return 1;
} else {
return LeafNum(T->lchild) + LeafNum(T->rchild);
}
}
int NotLeafNum(BiTree T) {
if (!T) {
return 0;
} else if (!T->lchild && !T->rchild) {
return 0;
} else {
return NotLeafNum(T->lchild) + NotLeafNum(T->rchild) + 1;
}
}
int BiTreeDepth(BiTree T) {
if (!T) {
return 0;
}
return BiTreeDepth(T->lchild) > BiTreeDepth(T->rchild) ?
1 + BiTreeDepth(T->lchild) : 1 + BiTreeDepth(T->rchild);
}
void main()
{ BiTree T=NULL;
T=create(T);
int lnum=LeafNum(T);
printf("叶子结点数是:%d",lnum);
printf("\n");
int nnum=NotLeafNum(T);
printf("非叶子结点树:%d",nnum);
printf("\n");
int depth=BiTreeDepth(T);
printf("树的深度是:%d",depth);
printf("\n");
printf("前序遍历的结果是:");
preorder(T);
printf("\n");
printf("中序遍历的结果是:");
inorder(T);
printf("\n");
printf("后序遍历的结果是:");
postorder(T);
printf("\n");
printf("层序遍历的结果是:");
levelorder(T);
printf("\n");
}
分析:
1.关于树的很多题目其实用递归的方法写会简化很多,例如前中后序遍历输出,也只是printf的位置不同罢了
2.树的深度问题 记得要+1,因为一开始树的深度就是为1 然后也是利用递归的思路,遍历左子树,右子树,一层一层比较深度的大小
3.叶子结点就是没有儿子的 也是递归 没有儿子return 1,然后递归找左右子树
4.非叶子结点就是有儿子的 注意我这里用到的因为前两个都是return 0的(一个条件是为空 一个条件是没有儿子)所以递归return的时候要+1