C语言数据结构(15)--二叉树的层序遍历代码实现

10 阅读 作者:慕课熊猫 2020-03-09

背景

在上一篇中,我们利用递归很轻易的就实现了二叉树的前序、中序、后续遍历,但是层序遍历仅仅利用递归貌似是解决不了的。

在如上图的树中,我们如何先从上至下,然后从左至右的按层次进行遍历,即A-B-C-D-E-F-G这样的顺序呢。

思路

每次在访问下一层次节点之前,应该将上一级节点输出,而上一级节点无疑从层次上先于下一级,我们联想到先进先出的队列模型,我们可以利用一个队列,在递归访问二叉树下一层次之前,将本层次的节点放入队列,这样就实现了输出时,也是按层次先后输出的。

代码实现

#include<stdio.h>
#define QUEUE_LENGTH 100 //队列最大元素个数
/*
* 二叉树的层序遍历演示DEMO
* 作者:熊猫大大
* 时间:2019-12-15
*/

// 队列结构体
struct Queue
{
	char element[QUEUE_LENGTH];//队列元素
	int head;//头部位置
	int tail;//尾部位置
};

//入队
int queueIn(struct Queue* p, char num)
{
	//满了
	if (p->tail>QUEUE_LENGTH - 1)
	{
		return 0;//入队失败
	}
	p->element[p->tail] = num;
	p->tail++;
	return 1;
}
//出队
int queueOut(struct Queue* p, char *result)
{
	if (p->head == p->tail)
		return 0;//出队失败
	*result = p->element[p->head++];
	return 1;
}
//定义一个全局的队列,用来层序遍历二叉树
struct Queue queue;

//二叉树结构体
typedef struct {
	char data;//数据区域(为了保存ABCD,直接用char当做数据域,便于和文章中的插图对应,稳!)
	struct BinaryTreeNode* left;//左子节点
	struct BinaryTreeNode* right;//右子节点
}BinaryTreeNode;

//为树的当前节点添加左子节点
int addLeftChild(BinaryTreeNode* curNode, char leftData)
{
	//分配新节点
	BinaryTreeNode* leftNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
	//为新节点挂载数据
	leftNode->data = leftData;
	//新节点暂时无子节点
	leftNode->left = NULL;
	leftNode->right = NULL;
	//将新节点挂到当前节点下
	curNode->left = leftNode;
	return 1;
}

//为树的当前节点添加右子节点
int addRightChild(BinaryTreeNode* curNode, char rightData)
{
	//分配新节点
	BinaryTreeNode* rightNode = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
	//为新节点挂载数据
	rightNode->data = rightData;
	//新节点暂时无子节点
	rightNode->left = NULL;
	rightNode->right = NULL;
	//将新节点挂到当前节点下
	curNode->right = rightNode;
	return 1;
}

// 层序遍历
void leverOrder(BinaryTreeNode *node)
{
	if (node == NULL) {
		return;
	}
	//输出队列中保存的信息
	char result;
	while (queueOut(&queue, &result) == 1) {
		printf("%c",result);
	}
	//将子节点先加入队列,后续再遍历更深的层次
	if (node->left != NULL) {
		BinaryTreeNode *temp = node->left;
		queueIn(&queue, temp->data);
	}
	if (node->right != NULL) {
		BinaryTreeNode *temp = node->right;
		queueIn(&queue, temp->data);
	}
	leverOrder(node->left);
	leverOrder(node->right);
}

//----------------------------------------------------------------------------------------------------测试入口区域
int main()
{
	//初始化队列
	queue.head = 0;
	queue.tail = 0;
	//设定根节点
	BinaryTreeNode root;
	//根节点A
	root.data = 'A';
	addLeftChild(&root, 'B');
	addRightChild(&root, 'C');
	//为B节点增加子节点
	addLeftChild(root.left, 'D');
	addRightChild(root.left, 'E');
	//为C节点增加子节点
	addLeftChild(root.right, 'F');
	addRightChild(root.right, 'G');
	printf("\n层序遍历:");
	//根节点第一个进入队列
	queueIn(&queue, root.data);
	leverOrder(&root);
	return 1;
}

点击查看更多内容
原文地址:https://www.imooc.com/article/297797
广告一下
热门教程
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0
相关文章
【译】JavaScript数据结构(3):单向链表与双向链表 16
10个JavaScript难点 16
【译】苹果拒绝支持PWA,有损Web的未来 16
iView 一周年了,同时发布了 2.0 正式版,但这只是开始... 16
nodejs+mongodb构建一个简单登录注册功能 16
【译】JavaScript数据结构(4):树 16
组件化开发与黑箱 16
TypeScript - 不止稳,而且快 16
webpack3+anujs+ReactCSSTransitionGroup 16
原生js实现图片放大镜效果 16
WEB缓存探究第二弹——实战 16
纯笔记:vfork 的一些使用场景(顺便讲一下 fork 的原理) 16
Android APP 内部捐赠实现(支付宝&amp;微信) 16
WKWebView 的一些小总结 16
模型评价(一) AUC大法 16
开始使用GraphQL 16
Webpack模块化原理简析 16
gulp使用问题记录 16
使用Angular4动画为页面添彩 16
Python27 Matplotlib (win64 python2.7) 安装及简单使用 16