#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
/* 实验内容
该程序的功能是实现二叉树结点的类型定义和对二叉树的基本操作。该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。
*/
/* 定义DataType为char类型 */
typedef char DataType;
/* 二叉树的结点类型 */
typedef struct BitNode{
DataType data;
struct BitNode *lchild,*rchild;
}BitNode,*BitTree;
/* 初始化二叉树,即把树根指针置空 */
void BinTreeInit(BitTree &BT)
{
BT = NULL;
}
/* 按先序次序建立一个二叉树*/
void BinTreeCreat(BitTree &BT)
{
//printf("请输入该节点的元素值:");
scanf("%c",&BT->data);
while(BT->data==' ' || BT->data=='\n'){
scanf("%c",&BT->data);
}
if(BT->data=='#'){ //输入为'#'说明该节点为空,返回上一步
BT=NULL;
return ;
}
BT->lchild = (BitNode*)malloc(sizeof(BitNode));
BT->rchild = (BitNode*)malloc(sizeof(BitNode));
printf("请输入%c的左节点\n",BT->data);
BinTreeCreat(BT->lchild);
printf("请输入%c的右节点\n",BT->data);
//printf("进入右子树\n");
BinTreeCreat(BT->rchild);
}
/* 检查二叉树是否为空 */
int BinTreeEmpty(BitTree BT)
{
if(BT==NULL)
return 1;
else
return 0;
}
/* 按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */
void BinTraverse1(BitTree BT) //按前序遍历
{
if(BT==NULL) //递归出口
return ;
printf("%c",BT->data);
BinTraverse1(BT->lchild);
BinTraverse1(BT->rchild);
}
/* 按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */
void BinTraverse2(BitTree BT) //按中序遍历
{
if(BT==NULL) //递归出口
return ;
BinTraverse2(BT->lchild);
printf("%c",BT->data);
BinTraverse2(BT->rchild);
}
/* 按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */
void BinTraverse3(BitTree BT) //按后序遍历
{
if(BT==NULL) //递归出口
return ;
BinTraverse3(BT->lchild);
BinTraverse3(BT->rchild);
printf("%c",BT->data);
}
/* 按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */
void BinTraverse4(BitTree BT) //按层次遍历
{
queue <BitTree> q;
BitTree cur = BT;
q.push(cur);
while(!q.empty()){ //队列空为止
cur = q.front();
q.pop();
if(cur==NULL) //遇到空节点退出本次循环
continue;
printf("%c",cur->data); //输出当前节点元素
q.push(cur->lchild); //将该节点的两个孩子节点入栈
q.push(cur->rchild);
}
}
/* 求二叉树的深度 */
int BinTreeDepth(BitTree BT)
{
if(BT==NULL) //递归出口
return 0;
//记录左子树深度和右子树深度,返回较大的深度+1
int ldp = BinTreeDepth(BT->lchild);
int rdp = BinTreeDepth(BT->rchild);
return ldp>rdp?ldp+1:rdp+1;
}
/* 求二叉树中所有结点数 */
int BinTreeCount(BitTree BT)
{
if(BT==NULL) //递归出口
return 0;
//返回左子树节点数和右子树节点数再加上当前节点
return BinTreeCount(BT->lchild) + BinTreeCount(BT->rchild) + 1;
}
/* 清除二叉树,使之变为空树 */
void BinTreeClear(BitTree &BT)
{
if(BT==NULL) //递归出口
return ;
//左右子树找到底,然后返回的时候依次销毁空间
BinTreeClear(BT->lchild);
BinTreeClear(BT->rchild);
free(BT);
BT=NULL;
}
int Menu() //菜单
{
int 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("[9] 清除二叉树,使之变为空树\n");
printf("[0] 退出\n");
scanf("%d",&n);
return n;
}
void Reply(BitTree &BT,int n) //对菜单的响应
{
switch(n){
case 1: //创建二叉树
if(BT!=NULL)
printf("已创建二叉树! 请先清除二叉树再创建!\n");
else{ //二叉树为空
printf("按先序依次增加节点,输入'#'表示空节点!\n\n");
BT = (BitNode*)malloc(sizeof(BitNode)); //创建根节点
BT->lchild = NULL;
BT->rchild = NULL;
printf("请输入根节点的元素值:\n");
BinTreeCreat(BT);
printf("\n二叉树创建成功!\n\n");
}
break;
case 2: //检查二叉树是否为空
if(BinTreeEmpty(BT))
printf("二叉树为空!\n\n");
else
printf("二叉树不为空!\n\n");
break;
case 3: //按前序遍历
if(BT==NULL){
printf("二叉树为空!无法遍历!\n\n");
break;
}
printf("前序遍历顺序为:\n");
BinTraverse1(BT);
printf("\n\n");
break;
case 4: //按中序遍历
if(BT==NULL){
printf("二叉树为空!无法遍历!\n\n");
break;
}
printf("中序遍历顺序为:\n");
BinTraverse2(BT);
printf("\n\n");
break;
case 5: //按后序遍历
if(BT==NULL){
printf("二叉树为空!无法遍历!\n\n");
break;
}
printf("后序遍历顺序为:\n");
BinTraverse3(BT);
printf("\n\n");
break;
case 6: //按层次遍历
if(BT==NULL){
printf("二叉树为空!无法遍历!\n\n");
break;
}
printf("层次遍历顺序为:\n");
BinTraverse4(BT);
printf("\n\n");
break;
case 7: //求二叉树的深度
printf("二叉树的深度为:%d\n\n",BinTreeDepth(BT));
break;
case 8: //求二叉树的节点数
printf("二叉树的总结点数为:%d\n\n",BinTreeCount(BT));
break;
case 9: //清除二叉树
if(BT==NULL){
printf("二叉树已经为空!无需清空!\n\n");
break;
}
BinTreeClear(BT);
printf("清除成功!\n\n");
break;
default:
exit(1);
}
system("pause");
system("cls");
}
int main()
{
BitTree BT = NULL;
BinTreeInit(BT); //初始化二叉树
while(1){
int n = Menu();
Reply(BT,n);
}
return 0;
}