C语言实现二叉树的遍历等操作

#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  )

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值