实验四 二叉树子系统
1.实验目的
(1)掌握二叉树的特点及其存储方式。
(2)掌握二叉树的创建和显示方法。
(3)复习二叉树遍历的概念,掌握二叉树遍历的基本方法。
2.实验内容
(1)按屏幕提示用前序方法建立一棵二叉树。
(2)编写各个函数:前序遍历、中序遍历、后序遍历、层次遍历、求二叉树的叶子结点数、求二叉树的总结点数、求二叉树的深度。
(3)设计一个选择式菜单,以菜单方式选择下列操作。
二叉树子系统
*******************************************
* 1------建二叉树 *
* 2------凹入显示 *
* 3------先序遍历 *
* 4------中序遍历 *
* 5------后序遍历 *
* 6------层次遍历 *
* 7------求叶子数 *
* 8------求结点数 *
* 9------求树深度 *
* 0------返 回 *
*******************************************
请选择菜单号(0--9):
3.实验步骤
(1)按下图建立二叉树。
(2)输入并调试程序。
(3)验证程序运行结果。
附:C程序清单如下:
#include<stdio.h>
#define TREEMAX 100
typedef struct BT
{ char data;
struct BT* lchild;
struct BT*rchild;
}BT;
BT *CreateTree();
void ShowTree(BT *T);
void Preorder(BT *T);
void Postorder(BT *T);
void Levelorder(BT *T);
void Inorder(BT *T);
void Nodenum(BT *T);
void Leafnum(BT *T);
int TreeDepth(BT *T);
int count=0;
void main()
{BT*T=NULL;
char ch1,ch2,a;
ch1='y';
while(ch1=='y'||ch1=='Y')
{printf("\n");
printf("\n\t\t 二叉树子系统");
printf("\n\t\t*****************************************");
printf("\n\t\t* 1----建二叉树 *");
printf("\n\t\t* 2----凹入显示 *");
printf("\n\t\t* 3----先序遍历 *");
printf("\n\t\t* 4----中序遍历 *");
printf("\n\t\t* 5----后序遍历 *");
printf("\n\t\t* 6----层次遍历 *");
printf("\n\t\t* 7----求叶子数 *");
printf("\n\t\t* 8----求结点数 *");
printf("\n\t\t* 9----求树深度 *");
printf("\n\t\t* 0----返回 *");
printf("\n\t\t*****************************************");
printf("\n\t\t 选择菜单号(0---9):");
scanf("%c",&ch2);
getchar();
printf("\n");
switch(ch2)
{ case '1':
printf("\n\t\t请按先序序列输入二叉树的结点: \n");
printf("\n\t\t说明:输入结点('0'表示后继结点为空)后按回车。 \n");
printf("\n\t\t请输入结点:");
T=CreateTree();
printf("\n\t\t 二叉树成功建立!\n");break;
case '2':
ShowTree(T);break;
case '3':
printf("\n\t\t 该二叉树的先序遍历数列为:");
Preorder(T);break;
case '4':
printf("\n\t\t 该二叉树的中序遍历数列为:");
Inorder(T);break;
case '5':
printf("\n\t\t 该二叉树的后序遍历数列为:");
Postorder(T);break;
case '6':
printf("\n\t\t 该二叉树的层次遍历数列为:");
Levelorder(T);break;
case '7':
count=0;Leafnum(T);
printf("\n\t\t 该二叉树总共有%d个叶子。\n",count);break;
case '8':
count=0;Nodenum(T);
printf("\n\t\t 该二叉树总共有%d个结点。\n",count);break;
case '9':
printf("\n\t\t 该树的高度是:%d",TreeDepth(T));break;
case '0':
ch1='n';break;
default:
printf("\n\t\t*** 请注意:输入有误!***");
}
if(ch2!='0')
{ printf("\n\n\t\t 按ENTER键继续,按任意键返回主菜单!\n");
a=getchar();
if(a!='\xA')
{getchar();ch1='n';}
}
}
}
BT *CreateTree()
{ BT *t;
char x;
scanf("%c",&x);
getchar();
if(x=='0')
t=NULL;
else
{t=(BT*)malloc(sizeof(BT));
t->data=x;
printf("\n\t\t请输入%c结点的左子结点:",t->data);
t->lchild=CreateTree();
printf("\n\t\t请输入%c结点的右子结点:",t->data);
t->rchild=CreateTree();
}
return t;
}
void Preorder(BT *T)
{ if(T)
{ printf("%3c",T->data);
Preorder(T->lchild);
Preorder(T->rchild);
}
}
void Inorder(BT *T)
{ if(T)
{
Preorder(T->lchild);
printf("%3c",T->data);
Preorder(T->rchild);
}
}
void Postorder(BT *T)
{ if(T)
{
Preorder(T->lchild);
Preorder(T->rchild);
printf("%3c",T->data);
}
}
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("%3c",p->data);
if(p->lchild!=NULL)
{q[j]=p->lchild;j++;}
if(p->rchild!=NULL)
{q[j]=p->rchild;j++;}
i++;
}
}
void Leafnum(BT *T)
{if(T)
{if(T->lchild==NULL&&T->rchild==NULL)
count++;
Leafnum(T->lchild);
Leafnum(T->rchild);
}
}
void Nodenum(BT *T)
{if(T)
{count++;
Nodenum(T->lchild);
Nodenum(T->rchild);
}
}
int TreeDepth(BT *T)
{int ldep,rdep;
if(T==NULL)
return 0;
else
{ldep=TreeDepth(T->lchild);
rdep=TreeDepth(T->rchild);
if(ldep>rdep)
return ldep+1;
else
return rdep+1;
}
}
void ShowTree(BT *T)
{BT *stack[TREEMAX],*p;
int level[TREEMAX][2],top,n,i,width=4;
if(T!=NULL)
{printf("\n\t\t 凹入表示法:\n\t\t");
top=1;
stack[top]=T;
level[top][0]=width;
while(top>0)
{p=stack[top];
n=level[top][0];
for(i=1;i<=n;i++)
printf(" ");
printf("%c",p->data);
for(i=n+1;i<30;i+=2)
printf("-");
printf("\n\t\t");
top--;
if(p->rchild!=NULL)
{top++;
stack[top]=p->rchild;
level[top][0]=n+width;
level[top][1]=2;
}
if(p->lchild!=NULL)
{top++;
stack[top]=p->lchild;
level[top][0]=n+width;
level[top][1]=1;
}
}
}
}
运行过程及结果:
1----建二叉树
2----凹入显示
3----先序遍历
4----中序遍历
5----后序遍历
6----层次遍历
7----求叶子数
8----求结点数
9----求树深度
0----返回