【数据结构】二叉树的前中后序遍历以及层序遍历(全解)

文章目录

  • 前言
  • [1. 前中后序遍历](#1. 前中后序遍历)
    • [1.1 遍历规则](#1.1 遍历规则)
    • [1.2 代码实现](#1.2 代码实现)
    • [1.3 图解遍历](#1.3 图解遍历)
  • [2. 层序遍历](#2. 层序遍历)
  • 3.结点个数以及高度等
  • [4. 判断是否为完全二叉树](#4. 判断是否为完全二叉树)
  • [5. 结语](#5. 结语)

前言

在前面学习完链式结构的二叉树之后,我们就可以进一步了解二叉树的几种遍历方式了,注意这里就可以深刻的体会到递归的思想了。

1. 前中后序遍历

二叉树的操作离不开树的遍历,我们先来看看二叉树的遍历有哪些方式

1.1 遍历规则

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

(1)前序遍历(Preorder Traversal 亦称先序遍历):访问根结点的操作发生在遍历其左右子树之前

访问顺序为:根结点、左子树、右子树

(2)中序遍历(Inorder Traversal):访问根结点的操作发生在遍历其左右子树之中(间)

访问顺序为:左子树、根结点、右子树

(3)后序遍历(Postorder Traversal):访问根结点的操作发生在遍历其左右子树之后

访问顺序为:左子树、右子树、根结点

1.2 代码实现

c 复制代码
//前序遍历
void PreOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	printf("%d ", root->val);
	PreOrder(root->left);
	PreOrder(root->right);
}

//中序遍历
void InOrder(BTNode * root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	InOrder(root->left);
	printf("%d ", root->val);
	InOrder(root->right);
}

//后序遍历
void PostOrder(BTNode * root)
{
	if (root == NULL)
	{
		printf("N ");
		return;
	}
	InOrder(root->left);
	InOrder(root->right);
	printf("%d ", root->val);
}

1.3 图解遍历

以前序遍历为例:

函数递归栈帧图

前序遍历结果:1 2 3 4 5 6

中序遍历结果:3 2 1 5 4 6

后序遍历结果:3 1 5 6 4 1

2. 层序遍历

除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根结点所在层数为1,层序遍历就是从所在二叉树的根结点出发,首先访问第一层的树根结点,然后从左到右访问第2层上的结点,接着是第三层的结点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历

在层序遍历这个地方就不可以和前面实现前中后序遍历一样使用递归的思想了。

实现层序遍历需要额外借助数据结构:队列

画图分析:在这里我们先让根节点(1)入队列,然后开始出队列。在出队列的同时,将它的左右孩子(2)、(3)分别入队列,以此类推,然后在(2)开始出队列的时候,将(2)的左右孩子分别入队列。这样就可以依次得到每一层结点了

c 复制代码
// 层序遍历
void LevelOrder(BTNode * root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode * top = QueueFront(&q);
		printf("%c ", top->data);
		QueuePop(&q);
		if (top->_left)
		{
			QueuePush(&q, top->_left);
		}
		if (top->_right)
		{
			QueuePush(&q, top->_right);
		}
	}
	QueueDesTroy(&q);
}

3.结点个数以及高度等

下面这些方法的实现都是基于上面遍历的思想,请读者自行去完成这些方法,深刻领会遍历的递归美学。如果有不明白的地方可以在讨论区发起讨论❤️❤️❤️

c 复制代码
// 二叉树结点个数
int BinaryTreeSize(BTNode * root);
// 二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode * root);
// 二叉树第k层结点个数
int BinaryTreeLevelKSize(BTNode * root, int k);
//二叉树的深度/⾼度
int BinaryTreeDepth(BTNode * root);
// 二叉树查找值为x的结点
BTNode * BinaryTreeFind(BTNode * root, BTDataType x);
// 二叉树销毁
void BinaryTreeDestory(BTNode * *root);

4. 判断是否为完全二叉树

c 复制代码
// 判断二叉树是否是完全二叉树
bool BinaryTreeComplete(BTNode * root)
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, root);
	while (!QueueEmpty(&q))
	{
		BTNode * top = QueueFront(&q);
		QueuePop(&q);
		if (top == NULL)
		{
			break;
		}
		QueuePush(&q, top->_left);
		QueuePush(&q, top->_right);
	}
	while (!QueueEmpty(&q))
	{
		BTNode * top = QueueFront(&q);
		QueuePop(&q);
		if (top != NULL)
		{
			QueueDesTroy(&q);
			return false;
		}
	}
	QueueDesTroy(&q);
	return true;
}

5. 结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

相关推荐
hccee10 分钟前
C# IO文件操作
开发语言·c#
hummhumm15 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊25 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
寻找码源35 分钟前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
Matlab精灵37 分钟前
Matlab科研绘图:自定义内置多款配色函数
算法·matlab
zmd-zk39 分钟前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟43 分钟前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
诚丞成1 小时前
滑动窗口篇——如行云流水般的高效解法与智能之道(1)
算法
Alive~o.01 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript