实验四 二叉树的综合应用
一、实验目的
掌握二叉树的遍历算法,熟练使用遍历算法进行问题的求解。
二、实验内容
对于给定的字符串“ABF#C#G##DE##H###”,用递归的方法实现以下算法:
(1)以二叉链表表示二叉树,建立一棵二叉树;
(2)输出二叉树的中序遍历结果;
(3)输出结点“C”的左右孩子的值;
(4)计算二叉树的深度;
(5)统计二叉树的叶子结点个数;
(6)统计二叉树的度为1的结点个数;
头文件及宏定义:
/*CaptainUniverse_ 2022.4.20*/
#include <stdio.h>
#include <stdlib.h>
int flag=1;//是否有该结点
typedef char ElemType;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
/*CaptainUniverse_ 2022.4.20*/
子函数声明:
/*CaptainUniverse_ 2022.4.20*/
void CreateBiTree(BiTree *);//创建一颗二叉树(约定用户遵照前序遍历输入数据)
void visit(ElemType);//访问二叉树结点的具体操作
void InOrderTraverse(BiTree);//中序遍历二叉树
void OutputChild(BiTree,ElemType);//输出某结点的左右孩子的值
int CountTreeDepth(BiTree);//计算二叉树的深度
int CountLeaves(BiTree);//统计二叉树的叶子结点个数
int CountLeafIsOne(BiTree);//统计二叉树的度为1的结点个数
void ChoiceList();//提示选项列表
/*CaptainUniverse_ 2022.4.20*/
子函数主体:
/*CaptainUniverse_ 2022.4.20*/
void CreateBiTree(BiTree *T)
{
char c;
scanf("%c",&c);
if('#'==c)
{
*T=NULL;
}
else
{
*T=(BiTNode *)malloc(sizeof(BiTNode));
(*T)->data=c;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
}
void visit(char c)
{
printf("%c",c);
}
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
visit(T->data);
InOrderTraverse(T->rchild);
}
else
{
printf("#");
}
}
void OutputChild(BiTree T,ElemType ch)
{
if(T)
{
if(T->data==ch)
{
flag=0;
if(T->lchild)
{
printf("该结点左孩子值为:");
visit(T->lchild->data);
putchar('\n');
}
else
{
printf("该结点左孩子值为空!\n");
}
if(T->rchild)
{
printf("该结点右孩子值为:");
visit(T->rchild->data);
putchar('\n');
}
else
{
printf("该结点右孩子值为空!\n");
}
}
else
{
OutputChild(T->lchild,ch);
OutputChild(T->rchild,ch);
}
}
}
int CountTreeDepth(BiTree T)
{
int left,right;
if(T)
{
left=CountTreeDepth(T->lchild);
right=CountTreeDepth(T->rchild);
if(left>right)
{
return left+1;
}
else
{
return right+1;
}
}
else
{
return 0;
}
}
int CountLeaves(BiTree T)
{
if(T)
{
if(!(CountLeaves(T->lchild)||CountLeaves(T->rchild)))
{
return 1;
}
else
{
return CountLeaves(T->lchild)+CountLeaves(T->rchild);
}
}
else
{
return 0;
}
}
int CountLeafIsOne(BiTree T)
{
if(T)
{
if(((T->lchild)&&(!T->rchild))||((T->rchild)&&(!T->lchild)))
{
return 1+CountLeafIsOne(T->lchild)+CountLeafIsOne(T->rchild);
}
else
{
return CountLeafIsOne(T->lchild)+CountLeafIsOne(T->rchild);
}
}
else
{
return 0;
}
}
void ChoiceList()
{
printf("--------------★-------------\n");
printf("|1.输出二叉树的中序遍历结果 |\n");
printf("|2.输出某节点的左孩子右孩子 |\n");
printf("|3. 计算二叉树的深度 |\n");
printf("|4.统计二叉树的叶子结点个数 |\n");
printf("|5. 统计度为1的结点个数 |\n");
printf("|0. 退出 |\n");
printf("|Powered by CaptainUniverse_|\n");
printf("--------------★-------------\n");
}
/*CaptainUniverse_ 2022.4.20*/
主函数:
/*CaptainUniverse_ 2022.4.20*/
int main()
{
ElemType ch;
BiTree T=NULL;
printf(" ☆☆☆☆欢迎使用☆☆☆☆\n\n");
printf(" ★注意★\n");
printf("1.如遇空结点则用'#'代替!且务必要输入'#'!\n");
printf("2.字符串将以“前序”建立一颗二叉树!\n\n");
printf("请输入一段字符串:\n");
CreateBiTree(&T);
while(1)
{
putchar('\n');
ChoiceList();
int choice;
fflush(stdin);
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("该二叉树以中序遍历为:\n");
InOrderTraverse(T);
putchar('\n');
break;
case 2:
getchar();
printf("请输入该结点的值:\n");
scanf("%c",&ch);
OutputChild(T,ch);
if(flag)
{
printf("没有找到该结点!\n");
flag=0;
}
break;
case 3:
printf("该二叉树的深度为:%d\n",CountTreeDepth(T));
break;
case 4:
printf("该二叉树叶子结点数为:%d\n",CountLeaves(T));
break;
case 5:
printf("该二叉树度为1结点数为:%d\n",CountLeafIsOne(T));
break;
case 6:
printf("\n愿世上再无递归!\n");
printf("/(ㄒoㄒ)/~~\n\n");
break;
case 0:
goto END;
default:
printf("输入有误请重新输入!\n");
break;
}
}
END: printf("感谢您的使用,再见!");
return 0;
}
/*CaptainUniverse_ 2022.4.20*/
附送两组测试数据:
第一组:ABF#C#G##DE##H###
第二组:ABD##E##CF###