#include <stdio.h>
#include <stdlib.h>
#define MAX_TREE_SIZE 100
typedef char DataType ;
typedef struct BiTNode{
DataType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//定义树遍历函数的指针
typedef void(*TREEORDER_FUN)(BiTree &BT);
//定义树结点计算函数的指针
typedef void(*TREEOPTR_FUN)(BiTree BT,int &count);
//先序顺序创建二叉树
void createBiTree(BiTree &BT)
{
char ch;
//接受用户输入节点的data域
scanf("%c",&ch);
//输入空格创建虚拟节点为NULL
if(ch == ' ')
{
BT = NULL;
}else
{
if(!(BT = (BiTree)malloc(sizeof(BiTNode))))
{
exit(1);
}
//建立根节点
BT->data = ch;
//创建左子树
createBiTree(BT->lchild);
//创建右子树
createBiTree(BT->rchild);
}
}
//递归先序遍历
void preOrder(BiTree BT)
{
if(BT!=NULL)
{
//访问根节点
printf("%c ",BT->data);
//遍历左子树
preOrder(BT->lchild);
//遍历右子树
preOrder(BT->rchild);
}
}
//递归中序遍历
void inOrder(BiTree BT)
{
if(BT!=NULL)
{
//遍历左子树
inOrder(BT->lchild);
//访问根节点
printf("%c ",BT->data);
//遍历右子树
inOrder(BT->rchild);
}
}
//递归后序遍历
void postOrder(BiTree BT)
{
if(BT!=NULL)
{
//遍历左子树
postOrder(BT->lchild);
//遍历右子树
postOrder(BT->rchild);
//访问根节点
printf("%c ",BT->data);
}
}
//迭代先序遍历
void preOrderByIteration(BiTree BT)
{
BiTree stack[100],p;
int top;
if(BT!=NULL)
{
top = 1;
//根节点入栈
stack[top] = BT;
//栈不为空时循环
while(top>0)
{
p = stack[top];
top--;
//输出节点数据域
printf("%c ",p->data);
//右孩子入栈
if(p->rchild != NULL)
{
top++;
stack[top] = p->rchild;
}
//左孩子入栈
if(p->lchild != NULL)
{
top++;
stack[top] = p->lchild;
}
}
}
}
//迭代中序遍历
void inOrderByIteration(BiTree BT)
{
BiTree stack[MAX_TREE_SIZE],p;
int top = 0;
p = BT;
do
{
//左节点全部入栈
while(p!=NULL)
{
top++;
stack[top] = p;
p = p->lchild;
}
if(top>0)
{
//出栈p节点
p = stack[top];
top--;
printf("%c ",p->data);
//扫描p的右孩子节点
p = p->rchild;
}
}while(p!=NULL || top>0);
}
//迭代后序遍历
void postOrderByIteration(BiTree BT)
{
BiTree stack[MAX_TREE_SIZE],p;
int tag[MAX_TREE_SIZE];
int top = 0;
p = BT;
do
{
//扫描p的左节点全部入栈
while(p!=NULL)
{
top++;
stack[top] = p;
p = p->lchild;
//表示当前节点的左子树已经访问过
tag[top] = 0;
}
if(tag>0)
{
//左右节点均已访问则访问该节点
if(tag[top]==1)
{
//访问节点
printf("%c ",stack[top] -> data);
top--;
}else
{
p = stack[top];
if(top > 0)
{
//扫描右节点
p = p->rchild;
tag[top] = 1;
}
}
}
}while(p!=NULL || top>0);
}
//叶子节点个数
void countLeaves(BiTree BT,int &count)
{
if(BT)
{
if(!BT->lchild && !BT->rchild)
{
count++;
}
//统计左子树节点个数
countLeaves(BT->lchild,count);
//统计左子树节点个数
countLeaves(BT->rchild,count);
}
}
//度为1的节点个数
void nodeCountWithOneDegree(BiTree BT,int &count)
{
if(BT)
{
if((!BT->lchild && BT->rchild) || (BT->lchild && !BT->rchild))
{
count++;
}
//统计左子树节点个数
nodeCountWithOneDegree(BT->lchild,count);
//统计左子树节点个数
nodeCountWithOneDegree(BT->rchild,count);
}
}
//度为2的节点个数
void nodeCountWithTwoDegree(BiTree BT,int &count)
{
if(BT)
{
if(BT->lchild && BT->rchild)
{
count++;
}
//统计左子树节点个数
nodeCountWithTwoDegree(BT->lchild,count);
//统计左子树节点个数
nodeCountWithTwoDegree(BT->rchild,count);
}
}
//总节点个数
void nodeCount(BiTree BT,int &count)
{
if(BT)
{
count++;
nodeCount(BT->lchild,count);
nodeCount(BT->rchild,count);
}
}
//树的高度
int bitTreeDepth(BiTree BT)
{
int lchilddep,rchilddep;
if(!BT)
{
return 0;
}else
{
//求左子树高度
lchilddep = bitTreeDepth(BT->lchild);
//求右子树高度
rchilddep = bitTreeDepth(BT->rchild);
return (lchilddep > rchilddep) ? (lchilddep+1):(rchilddep+1);
}
}
//方便操作后直观看到操作结果
void contiueOperate()
{
putchar(10);
putchar(10);
printf("按任意键继续操作.....\n");
getchar();
getchar();
}
//是否已经创建二叉树
int whetherCreate(BiTree BT)
{
if(BT==NULL)
{
printf("请按先序顺序创建一个二叉树\n\n");
contiueOperate();
return 0;
}
return 1;
}
//图形界面操作1对应的函数
void fun1(BiTree &bt)
{
printf("请按先序顺序输入二叉树的结点\n");
getchar();
createBiTree(bt);
contiueOperate();
}
//图形界面操作2对应的函数
void fun2(BiTree &bt)
{
//判断二叉树是否创建
if(!whetherCreate(bt))return;
printf("递归先序遍历的结果为:");
preOrder(bt);
contiueOperate();
}
void fun3(BiTree &bt)
{
if(!whetherCreate(bt))return;
printf("递归中序遍历的结果为:");
inOrder(bt);
contiueOperate();
}
void fun4(BiTree &bt)
{
if(!whetherCreate(bt))return;
printf("递归后序遍历的结果为:");
postOrder(bt);
contiueOperate();
}
void fun5(BiTree &bt)
{
if(!whetherCreate(bt))return;
printf("迭代先序遍历的结果为:");
preOrderByIteration(bt);
contiueOperate();
}
void fun6(BiTree &bt)
{
if(!whetherCreate(bt))return;
printf("迭代中序遍历的结果为:");
inOrderByIteration(bt);
contiueOperate();
}
void fun7(BiTree &bt)
{
if(!whetherCreate(bt))return;
printf("迭代后序遍历的结果为:");
postOrderByIteration(bt);
contiueOperate();
}
void fun8(BiTree bt,int &count)
{
if(!whetherCreate(bt))return;
count = 0;
countLeaves(bt,count);
printf("树的叶子节点为:%d个",count);
contiueOperate();
}
void fun9(BiTree bt,int &count)
{
if(!whetherCreate(bt))return;
count = 0;
nodeCountWithOneDegree(bt,count);
printf("度为一的节点为:%d个",count);
contiueOperate();
}
void fun10(BiTree bt,int &count)
{
if(!whetherCreate(bt))return;
count = 0;
nodeCountWithTwoDegree(bt,count);
printf("度为二的节点为:%d个",count);
contiueOperate();
}
void fun11(BiTree bt,int &count)
{
if(!whetherCreate(bt))return;
count = 0;
nodeCount(bt,count);
printf("树的总节点个数为:%d个",count);
contiueOperate();
}
void fun12(BiTree bt,int &count)
{
if(!whetherCreate(bt))return;
printf("树的高度为:%d",bitTreeDepth(bt));
contiueOperate();
}
void fun13(BiTree bt,int &count)
{
exit(1);
}
//用户界面
void enterView(BiTree BT)
{
printf("=====================================\n");
printf("|| 请输入你的操作: ||\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.计算度为1的节点的个数 ||\n");
printf("|| 10.计算度为2的节点的个数 ||\n");
printf("|| 11.计算树的总节点数 ||\n");
printf("|| 12.计算树的高度 ||\n");
printf("|| 0.退出 ||\n");
printf("=====================================\n");
if(BT==NULL){
printf("提示:你当前输入二叉树的先序序列为:未创建二叉树\n\n");
}else{
printf("提示:你当前输入二叉树的先序序列为:");
preOrder(BT);
putchar(10);
putchar(10);
putchar(10);
}
}
//二叉树操作入口函数
void binaryTreeOperate()
{
BiTree bt = NULL;
int count = 0;
TREEORDER_FUN order_fun[7] = {fun1,fun2,fun3,fun4,fun5,fun6,fun7};
TREEOPTR_FUN optr_fun[6] = {fun8,fun9,fun10,fun11,fun12,fun13};
while(true){
int result;
//界面显示
enterView(bt);
printf("请输入你的选择:");
scanf("%d",&result);
putchar(10);
if(result < 1 || result > 12)
{
printf("输入有误重新输入!");
continue;
}
//通过函数指针数组高效访问函数
if(result < 8)
order_fun[result-1](bt);
else{
optr_fun[result-8](bt,count);
}
}
}
int main(void)
{
binaryTreeOperate();
return 0;
}
输入内容测试(括号内的内容):(abc de f g )