栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言二叉树的基本操作(超全)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言二叉树的基本操作(超全)

二叉树作为数据结构其实是一个挺有意思的结构,可以有多种应用
我们直接来看一下二叉树的代码:

#include
#include
#include
#include

#define maxsize 100

//二叉树的基本操作:建立,前序,中序,后序,层次,求叶子数,求层数,求结点树
//二叉树的数据结构
//创建数据域和左右指针域
typedef struct Tree
{
	char data;
	struct tree* lchild;
	struct tree* rchild;
}tree;

//建立二叉数初始化
void inittree(tree* root)
{
	root->data = "";
	root->rchild = NULL;
	root->lchild = NULL;
}

//二叉数的创建
tree* create(tree* root)
{
	char value;
	scanf_s("%c", &value);
	if (value == '#')
	{
		root = NULL;
	}
	else
	{
		root = (tree*)malloc(sizeof(tree));
		root->data = value;
		root->lchild = create(root->lchild);
		root->rchild = create(root->rchild);
	}
	return root;
}

//创建二叉树的结点(二级指针写法)
void createnode(tree** node)
{
	char p_data;
	scanf_s("%c", &p_data);
	if (p_data == '#')
	{
		*node = NULL;
	}
	else
	{
		*node = (tree*)malloc(sizeof(tree));
		(*node)->data = p_data;
		createnode(&((*node)->lchild));
		createnode(&((*node)->rchild));
	}
}

//判断二叉树是否为空
int tempty(tree* root)
{
	if (root->data == "")
	{
		printf("二叉树为空n");
		return 0;
	}
	else
	{
		printf("二叉树不为空n");
		return 1;
	}
}

//先序遍历(递归)
void porder(tree* root)
{
	if (root != NULL)
	{
		printf("%ct", root->data);
		porder(root->lchild);
		porder(root->rchild);
	}
}

//中序遍历(递归)
void morder(tree* root)
{
	if (root != NULL)
	{
		morder(root->lchild);
		printf("%ct", root->data);
		morder(root->rchild);
	}
}

//后序遍历(递归)
void torder(tree* root)
{
	if (root != NULL)
	{
		torder(root->lchild);
		torder(root->rchild);
		printf("%ct", root->data);
	}
}

//先序遍历非递归
//访问左子树的结点存入栈中(继续深入)直到无法访问再让其出栈回退访问右子树
void p_order(tree* root)
{
	if (root == NULL)
	{
		return;
	}
	tree* box[10];//创建栈存储每次打印结点的位置
	int box_top = -1;//栈顶的标记,为和数组下标保持一致
	tree* move = root;//从根节点开始打印
	while (box_top != -1 || move)
	{
		while (move)
		{
			//把路径入栈并且打印结点
			printf("%ct", move->data);
			box[++box_top] = move;//把结点存入数组中
			move = move->lchild;//移动到存入结点的左子树
		}
		if (box_top != -1)//判断如果访问完左子树
		{
			move = box[box_top];//获取栈顶元素
			box_top--;//回溯
			move = move->rchild;//移动访问右子树
		}
	}
}

//中序遍历非递归
//持续深入左子树并且存储结点直到无法深入然后回溯并且打印,出栈再访问右子树
void m_order(tree* root)
{
	tree* box[10];//创建栈,用于存放结点的位置
	int box_top = -1;//定义栈顶的标记
	tree* move = root;//定义移动的指针
	while (box_top != -1 || move)
	{
		//深入访问左子树
		while (move)
		{
			box[++box_top] = move;
			move = move->lchild;
		}
		if (box_top != -1)
		{
			move = box[box_top--];//获取栈顶元素且回溯
			printf("%ct", move->data);
			move = move->rchild;//移动到右子树
		}
	}
}

//后序遍历非递归
//先访问左子树一直深入直到无法访问,打印结点然后回溯,再访问右子树,在打印回溯,会出现两个树根
//定义访问标记如果访问过就不再打印来解决回溯后多次打印的问题
void t_order(tree* root)
{
	if (root == NULL)
	{
		return;
	}
	tree* box[10];
	int box_top = -1;
	tree* move = root;
	tree* visit = NULL;//访问标记
	while (move)
	{
		box[++box_top] = move;
		move = move->lchild;
	}
	while (box_top != -1)
	{
		move = box[box_top--];
		if (move->rchild == NULL || move->rchild == visit)//判断当前结点的右子树是否被访问
		{
			printf("%ct", move->data);
			visit = move;//改变标记的位置就是回溯到上一层的树根
		}
		else
		{
			box[++box_top] = move;
			move = move->rchild;
			while (move)
			{
				box[++box_top] = move;
				move = move->lchild;
			}
		}
	}

}

//二叉树求叶子数
int leaves(tree* root)
{
	if (root == NULL)
	{
		return 0;
	}
	else if (root->lchild == NULL && root->rchild == NULL)
	{
		return 1;
	}
	else
	{
		return leaves(root->lchild) + leaves(root->rchild);
	}
}

//求树深度的递归算法
int deep(tree* root)
{
	int lnum, rnum;
	if (root == NULL)
	{
		return 0;
	}
	else
	{
		lnum = deep(root->lchild);
		rnum = deep(root->rchild);
		return (lnum > rnum ? lnum : rnum) + 1;
	}
}

//求二叉树中以某值为根的子树深度(递归)
void x_deep(tree* root , char x)
{
	int lnum = 0, rnum = 0;
	if (root == NULL)
	{
		printf("空树深度为0n");
	}
	if (root->data == x)
	{
		printf("%dn", deep(root));
	}
	else
	{
		if (root->lchild)
		{
			x_deep(root->lchild, x);
		}
		if (root->rchild)
		{
			x_deep(root->rchild, x);
		}
	}
}

//二叉树求指定结点的层数
int floor(tree* root, char x)
{
	int lnum, rnum, fnum;
	if (root == NULL)
	{
		fnum = 0;
	}
	else if (root->data == x)
	{
		fnum = 1;
	}
	else
	{
		lnum = floor(root->lchild, x);
		rnum = floor(root->rchild, x);
		if (lnum == 0 && rnum == 0)//查找失败
		{
			
			fnum = 0;
		}
		else
		{
			fnum = ((lnum > rnum) ? lnum : rnum) + 1;
		}
	}
	return fnum;
}


//统计数中结点个数
int nodenum(tree* root)
{
	if (root == NULL)
	{
		return 0;
	}
	else
	{
		return(nodenum(root->lchild) + nodenum(root->rchild)) + 1;
	}
}

//层序遍历BFS
//准备工作:构造队列
typedef struct queue
{
	tree* qdata[maxsize];
	int front;
	int rear;
}q;

//对队列进行初始化
void initqueue(q* node)
{
	node->front = node->rear = 0;
}

//判断队列是否为空
void empty(q* node)
{
	if (node->front == node->rear)
	{
		printf("队列为空");
	}
}

//入队
void push(q* node, tree* root)
{
	node->qdata[node->rear] = root;
	node->rear++;
}

//出队
tree* pop(q* node, tree* root)
{
	return node->qdata[(++node->front) - 1];
}

//二叉树层次遍历BFS
void BFS(tree* root)
{
	q* node;
	node = (q*)malloc(sizeof(q));
	initqueue(node);
	if (root != NULL)
	{
		push(node, root);
	}
	while (node->front != node->rear)
	{
		tree* root1 = (tree*)malloc(sizeof(tree));
		root1 = pop(node, root1);
		printf("%ct", root1->data);
		if (root1->lchild != NULL)
		{
			push(node, root1->lchild);
		}
		if (root1->rchild != NULL)
		{
			push(node, root1->rchild);
		}
	}
}

int main()
{
	//测试:12#46###3#5##,ABC##DE#G##F###
	tree* root = (tree*)malloc(sizeof(tree));
	inittree(root);
	printf("请按先序遍历的次序输入二叉树:n");
	root = create(root);
	int temp;
	while (1)
	{
		printf("*****************************二叉树综合实验****************************n");
		printf("*****************************1.二叉树先序遍历**************************n");
		printf("*****************************2.二叉树中序遍历**************************n");
		printf("*****************************3.二叉树后序遍历**************************n");
		printf("*****************************4.二叉树先序遍历(非递归)****************n");
		printf("*****************************5.二叉树先序遍历(非递归)****************n");
		printf("*****************************6.二叉树先序遍历(非递归)****************n");
		printf("*****************************7.二叉树层次遍历(BFS)*******************n");
		printf("*****************************8.求二叉树深度(递归)********************n");
		printf("*****************************9.二叉树求叶子数**************************n");
		printf("*****************************10.二叉树求结点数*************************n");
		printf("*****************************11.二叉树求指定结点所在的层数*************n");
		printf("*****************************12.判断二叉树是否为空树*******************n");
		printf("*****************************13.求二叉树中以某值为根的子树深度(递归)*n");
		printf("*****************************14.退出exit*******************************n");
		printf("***********************************************************************n");
		printf("输入你的选项:");
		scanf_s("%d", &temp);
		if (temp == 14)
		{
			printf("程序退出》》》");
			break;
		}
		switch (temp)
		{
			case 1:
				printf("二叉树前序遍历(递归)为:n");
				porder(root);
				printf("n");
				break;
			case 2:
				printf("二叉树中序遍历(递归)为:n");
				morder(root);
				printf("n");
				break;
			case 3:
				printf("二叉树后序遍历(递归)为:n");
				torder(root);
				printf("n");
				break;
			case 4:
				printf("二叉树前序遍历为:n");
				p_order(root);
				printf("n");
				break;
			case 5:
				printf("二叉树中序遍历为:n");
				m_order(root);
				printf("n");
				break;
			case 6:
				printf("二叉树后序遍历为:n");
				t_order(root);
				printf("n");
				break;
			case 7:
				printf("BFS层序遍历二叉树:n");
				BFS(root);
				printf("n");
				break;
			case 8:
				printf("二叉树的深度为%d层n", deep(root));
				break;
			case 9:
				printf("二叉树中含有%d个叶子结点n", leaves(root));
				break;
			case 10:
				printf("二叉树共有%d个结点n", nodenum(root));
				break;
			case 11:
			{
				char x;
				printf("请输入你要查找的结点:");
				scanf_s(" %c", &x);//注意:一定要在%c前加个blank,让缓冲区置空!
				printf("当前结点所在的层数为:%dn", floor(root, x));
			}
			break;
			case 12:
				tempty(root);
				printf("n");
				break;
			case 13:
			{
				char x2;
				printf("请输入你要查找的结点:");
				scanf_s(" %c", &x2);
				printf("以%c为子树的深度为:",x2);
				x_deep(root, x2);
				printf("n");
			}
			break;
			default:
				printf("error");
				break;
		}
	}
	return 0;
}

程序执行结果:






转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/850854.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号