二叉树链式结构的前序_中序_后续_层序遍历【详细图解】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

在这里插入图片描述

                                           博主主页:LiUEEEEE
                                              C语言专栏
                                            数据结构专栏
                                         力扣牛客经典题目专栏

1、前言


  有关二叉树链式结构的四种遍历方式,是基于二叉树由链式结构组成,故本文不再讲解如何实现二叉树的链式结构,以手搓链式结构的方式进行四种遍历方式的讲解。
  • 结点结构及相关定义展示:
typedef int TreeDataType;

typedef struct TreeNode
{
	TreeDataType val;
	struct TreeNode* left;
	struct TreeNode* right;
}TNode;

TNode* BuyNode(TreeDataType x);创建二叉树结点

TNode* CreateTree();串连结点组成树
  • BuyNode
TNode* BuyNode(TreeDataType x)
{
	TNode* tmp = (TNode*)malloc(sizeof(TNode));
	if (tmp == NULL)
	{
		perror("BuyNode: malloc fail");
		return NULL;
	}
	tmp->val = x;
	tmp->left = tmp->right = NULL;
	return tmp;
}
  • CreateTree
TNode* CreateTree()
{
	TNode* node1 = BuyNode(1);
	TNode* node2 = BuyNode(2);
	TNode* node3 = BuyNode(3);
	TNode* node4 = BuyNode(4);
	TNode* node5 = BuyNode(5);
	TNode* node6 = BuyNode(6);

	node1->left = node2;
	node1->right = node3;
	node2->left = node4;
	node2->right = node5;
	node3->left = node6;

	return node1;
}

  再此基础上我们所构建的书逻辑图如下所示:
在这里插入图片描述
PS.图中子树未连接部分均为NULL。




2、前序遍历


  遍历的命名规则为,以每一颗树的根为主要节点(整个树的根以及子树的根),以根出现的次序进行命名,下文中的中序后续皆可以此理解。
  前序遍历:遍历的顺序依次为:根,左子树,右子树。
  例如上文中我们手搓的二叉树,通过前序遍历的过程并打印的结果如下图所示:

在这里插入图片描述

  • 前序遍历代码实现
void PreOrder(TNode* root)
{
	if (root == NULL)
		return;
	printf("%d ", root->val);

	PreOrder(root->left);
	PreOrder(root->right);
}




3、中序遍历


  中序遍历:遍历的顺序依次为:左子树,根,右子树。
  例如上文中我们手搓的二叉树,通过中序遍历的过程并打印的结果如下图所示:

在这里插入图片描述

  • 中序遍历代码实现
void InOrder(TNode* root)
{
	if (root == NULL)
		return;

	InOrder(root->left);

	printf("%d ", root->val);

	InOrder(root->right);
}




4、后序遍历


  后序遍历:遍历的顺序依次为:左子树,右子树,根。
  例如上文中我们手搓的二叉树,通过后序遍历的过程并打印的结果如下图所示:

在这里插入图片描述

  • 后序遍历代码实现
void PostOrder(TNode* root)
{
	if (root == NULL)
		return;

	PostOrder(root->left);

	PostOrder(root->right);

	printf("%d ", root->val);
}




5、层序遍历


  层序遍历是指按照层数从每层的最左侧向右依次打印二叉树的节点值,如下图所示:

在这里插入图片描述


  但我们实际中很难使用递归来操作,使得再打印完2时,通过结点1找到结点3的值打印,故我们需要借助其他工具进行实现,即队列。


  操作原则是,先将根结点1输入到队列中,在打印根结点1时,将结点1的左结点与右结点依次输入进队列,并将结点1从队列中删除,以此往复,直至在队列中遇见空结点。
  对此本文不再对队列相关的知识进行讲解,如有需要回看博文:

                     队列的实现(使用链表)


  逻辑思路如下图所示:

在这里插入图片描述

  • 层序遍历代码实现
void LevelOrder(TNode* root)
{
	Queue pq;
	QueueInit(&pq);

	if (root)
		QueuePush(&pq, root);

	while (!QueueEmpty(&pq))
	{
		TNode* front = QueueFront(&pq);

		QueuePop(&pq);

		printf("%d ", front->val);

		if (front->left)
			QueuePush(&pq, front->left);

		if (front->right)
			QueuePush(&pq, front->right);
	}
	QueueDestroy(&pq);
}
  • 四种遍历方式结果展示
    在这里插入图片描述




6、完整代码展示


   P,S.本章节所展示代码不包含队列代码,如有需求请自行添加。
  • Tree.h
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>


typedef int TreeDataType;

typedef struct TreeNode
{
	TreeDataType val;
	struct TreeNode* left;
	struct TreeNode* right;
}TNode;

TNode* BuyNode(TreeDataType x);

TNode* CreateTree();

void PreOrder(TNode* root);

void InOrder(TNode* root);

void PostOrder(TNode* root);

void LevelOrder(TNode* root);
  • Tree.c
#include "Tree.h"
#include "Queue.h"

TNode* BuyNode(TreeDataType x)
{
	TNode* tmp = (TNode*)malloc(sizeof(TNode));
	if (tmp == NULL)
	{
		perror("BuyNode: malloc fail");
		return NULL;
	}
	tmp->val = x;
	tmp->left = tmp->right = NULL;
	return tmp;
}

TNode* CreateTree()
{
	TNode* node1 = BuyNode(1);
	TNode* node2 = BuyNode(2);
	TNode* node3 = BuyNode(3);
	TNode* node4 = BuyNode(4);
	TNode* node5 = BuyNode(5);
	TNode* node6 = BuyNode(6);

	node1->left = node2;
	node1->right = node3;
	node2->left = node4;
	node2->right = node5;
	node3->left = node6;

	return node1;
}


void PreOrder(TNode* root)
{
	if (root == NULL)
		return;
	printf("%d ", root->val);

	PreOrder(root->left);
	PreOrder(root->right);
}

void InOrder(TNode* root)
{
	if (root == NULL)
		return;

	InOrder(root->left);

	printf("%d ", root->val);

	InOrder(root->right);
}

void PostOrder(TNode* root)
{
	if (root == NULL)
		return;

	PostOrder(root->left);

	PostOrder(root->right);

	printf("%d ", root->val);
}

void LevelOrder(TNode* root)
{
	Queue pq;
	QueueInit(&pq);

	if (root)
		QueuePush(&pq, root);

	while (!QueueEmpty(&pq))
	{
		TNode* front = QueueFront(&pq);

		QueuePop(&pq);

		printf("%d ", front->val);

		if (front->left)
			QueuePush(&pq, front->left);

		if (front->right)
			QueuePush(&pq, front->right);
	}
	QueueDestroy(&pq);
}
  • TreeTest.c
#include "Tree.h"

void test()
{
	TNode* root = CreateTree();
	printf("前序遍历结果:");
	PreOrder(root);
	printf("\n");
	printf("中序遍历结果:");
	InOrder(root);
	printf("\n");
	printf("后序遍历结果:");
	PostOrder(root);
	printf("\n");
	printf("层序遍历结果:");
	LevelOrder(root);
	printf("\n");
}

int main()
{
	test();

	return 0;
}




7、结语


在这里插入图片描述

  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值