《数据结构》课程中,基于递归调用的二叉树的3种遍历算法及其应用是一项重要内容。本文在编程实现基于递归调用的遍历二叉树常用的3种算法之前,先使用先序遍历扩展序列来创建二叉树,再依次使用3种基于递归的遍历算法来输出各自的遍历结果,并进行2种基本应用:统计叶子结点、计算二叉树高度,将这些算法汇总之后写出基于简单图形界面的程序,其运行结果示例及详细代码分别如下所示:
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
# define OK 1
# define OVERFLOW -2
typedef int Status;
typedef char BiTreeElemType;
typedef struct BiTreeNode{
BiTreeElemType data;
struct BiTreeNode *LChild, *RChild;
}BiTreeNode,*BiTree;
//按先序扩展序列创建二叉树
Status CreateBiTree(BiTree *T)
{
BiTreeElemType data;
scanf("%c",&data);
if (data == '#')
*T = NULL;
else
{
*T = (BiTreeNode *) malloc(sizeof(BiTreeNode));
if (*T == NULL) exit(OVERFLOW);
(*T)->data = data;
CreateBiTree(&(*T)->LChild);
CreateBiTree(&(*T)->RChild);
}
return OK;
}
// 其它选项界面
void InterfaceOfChoice()
{
int i;
printf("\n ");
for(i=0; i<40; i++)
printf("-");
printf("\n| 0--退出系统 |");
printf("\n| 1--先序遍历 |");
printf("\n| 2--中序遍历 |");
printf("\n| 3--后序遍历 |");
printf("\n| 4--统计叶子结点数 |");
printf("\n| 5--计算二叉树高度 |\n ");
for(i=0;i<40;i++)
printf("-");
}
// 先序递归遍历输出:
void PreOrder(BiTree T)
{
if(T)
{
printf("%c",T->data);
PreOrder(T->LChild);
PreOrder(T->RChild);
}
}
// 中序递归遍历输出:
void InOrder(BiTree T)
{
if(T)
{
InOrder(T->LChild);
printf("%c",T->data);
InOrder(T->RChild);
}
}
// 后序递归遍历输出:
void PostOrder(BiTree T)
{
if(T)
{
PostOrder(T->LChild);
PostOrder(T->RChild);
printf("%c",T->data);
}
}
// 统计二叉树叶子结点个数
int CountLeaf(BiTree T)
{
int count;
if(T == NULL)
count = 0;
else if(T->LChild == NULL && T->RChild == NULL)
count = 1;
else
count = CountLeaf(T->LChild) + CountLeaf(T->RChild);
return count;
}
// 计算二叉树高度
int CalHeight(BiTree T)
{
int height, hl, hr;
if(T == NULL)
height = 0;
else
{
hl = 1 + CalHeight(T->LChild);
hr = 1 + CalHeight(T->RChild);
height = (hl>hr?hl:hr);
}
return height;
}
// 主程序
int main()
{
// 按先序扩展序列输入数据来创建二叉树
BiTreeNode *t = NULL;
int result;
char choice;//后续用于用户选择数字序号
printf("\n请按先序序列输入各结点字符来创建二叉树,子树为空时输入'#'表示(如:AB##C#D##):");
result = CreateBiTree(&t);
if (result == 1 && t)
printf("\n恭喜您,二叉树创建成功!\n");
else if (!t)
{
printf("\n该二叉树是空树!\n");
exit(0);
}
else
printf("\n对不起,二叉树创建失败!\n");
// 选择其它操作序号并回车执行:
InterfaceOfChoice();
printf("\n请输入要选择的其它操作对应的数字序号(0-5):");
// 根据用户输入的序号来选择不同的分支执行对应操作,直到输入'0'结束程序:
scanf(" %c",&choice); //注意:%c前面要留有空格,目的是防止读入前面的回车符
while(choice != '0')
{
if(choice < '0' || choice >= '6')
printf("\n请重新输入正确的数字序号:");
else
{
switch(choice)
{
case '1':printf("\n二叉树的先序序列为:"); PreOrder(t); break;
case '2':printf("\n二叉树的中序序列为:"); InOrder(t); break;
case '3':printf("\n二叉树的后序序列为:"); PostOrder(t); break;
case '4':printf("\n二叉树的叶子结点个数为:%d", CountLeaf(t)); break;
case '5':printf("\n二叉树的高度为:%d", CalHeight(t)); break;
}
printf("\n请输入要选择的其它操作对应的数字序号(0-5):");
}
scanf(" %c",&choice);
}
printf("程序结束,再见!");
return 0;
}