博主主页:LiUEEEEE
C语言专栏
数据结构专栏
力扣牛客经典题目专栏
目录
- 1、前言
- 2、前序遍历
- 3、中序遍历
- 4、后序遍历
- 5、层序遍历
- 6、完整代码展示
- 7、结语
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、结语
十分感谢您观看我的原创文章。
本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
如需引用,注明地址。