【数据结构】前中后层序遍历 --二叉树的结构特点与遍历方式

简介: 与之前链表的Node类似,所以就不细讲了(给定一个值,malloc其节点,将值存入x,其左右指针置空,返回这个节点值)

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。


🌈个人主页:主页链接


🌈算法专栏:专栏链接


    我会一直往里填充内容哒!


🌈LeetCode专栏:专栏链接


目前在刷初级算法的LeetBook 。若每日一题当中有力所能及的题目,也会当天做完发出


🌈代码仓库:Gitee链接


🌈点击关注=收获更多优质内容🌈


809c89c988374fe381cdefdcb34edbf4.jpg


0.二叉树的链式结构实现


上文提到过,在简单二叉树当中,我们一般采用双指针链式结构存储的方式,其结构长这样


ed97ad0024fa4014b3034d659fb1ccc9.jpg


其结构体中包含三个值 left,right,val三个值


struct tree{
    int val;
    tree* left;
    tree* right;
}; 


为了方便之后遍历的调试,我们先初始化下这颗二叉树


先来看看BuyNode():


与之前链表的Node类似,所以就不细讲了(给定一个值,malloc其节点,将值存入x,其左右指针置空,返回这个节点值)


tree* BuyNode(TDataType x)
{
  tree* tmp = (tree*)malloc(sizeof(tree));
  tmp->x = x;
  tmp->left = NULL;
  tmp->right = NULL;
  return tmp;
}


之后将每个节点连接起来.


tree* CreateTree()
{
  tree* node1 = BuyNode(1);
  tree* node2 = BuyNode(2);
  tree* node3 = BuyNode(3);
  tree* node4 = BuyNode(4);
  tree* node5 = BuyNode(5);
  tree* node6 = BuyNode(6);
  tree* node7 = BuyNode(7);
  node1->left = node2;
  node1->right = node4;
  node2->left = node3;
  node4->left = node5;
  node4->right = node6;
  return node1;
}


连接图就长这样.


0a552c3b5e3e4e419d8b00f842593d0c.jpg


初始化完二叉树,就开始进入正题吧!


1.前序遍历:


树是一个递归的过程,所以进行遍历的时候,往往采用递归的方法比较简单(代码上),思维上当你理解了递归,也会发现就不过如此.


我们先来了解下前序遍历的含义:前序遍历顾名思义就是从根开始遍历,其遍历顺序为 先访问根再访问其左节点,之后才是右节点,对于每一颗子树都是如此.

例如这幅图,其先遍历根(1) 在遍历其左子树

进入左子树时,先访问其根(2) 在遍历其左子树

进入左子树时,先访问其根(3) 在遍历其左子树  发现为空!再遍历右子树,发现也为空,则返回到上一层(2)

此时再遍历根为(2)的右子树 发现为空,则返回到上一层(1)

此时在遍历其右子树

先访问其根(4)在遍历其左子树

进入左子树时,先访问其根(5) 在遍历其左子树  发现为空!再遍历右子树,发现也为空,则返回到上一层(4)

此时再访问根为(4)的右子树 其根为(6) 左右子树都为空则返回.

返回到根为1的节点就结束了

直接看文字似乎十分的绕,下面可以看看这幅图

d5407401909a426f8b6ffbbbe655bb77.jpg


所以前序遍历结果为:1 2 3 4 5 6,第一个为该树的根


1.1前序遍历代码实现


void Preorder(tree* tr)
{
  if (tr == NULL)
  {
    printf("NULL  ");
    return;
  }
  printf("%d  ", tr->x);
  Preorder(tr->left);
  Preorder(tr->right);
}


这是模板,遇到节点直接打印,空的话就返回到上一层当中.虽然这代码十分的简短,但第一次遇到的时候,其背后的思考量还是很大的.


以下为递归展开图,推荐自己动手画一下.


834dc60ffaa44708869595d2b44c3106.jpg


1.2深度优先搜索


这与深度优先搜索十分的相似


2.中序遍历:


中序遍历相较于前序改变的只是遍历根的顺序,前序为:根左右 根在前


所以中序遍历为:左根右 先遍历完左子树,在访问 其根节点,再遍历其右子树


0a552c3b5e3e4e419d8b00f842593d0c.jpg


其遍历完的结果为:321546


其遍历顺序是这样的. 可以看出他会先走到最左边的节点 访问(因为没有左右节点了),之后访问此左节点的根节点,之后是右节点

又因为这个根节点又有其父节点,所以以此类推.

7c3ed29979fc49a3a12f261b70019e8e.jpg


2.1中序遍历代码实现


void Inorder(tree* tr)
{
  if (tr == NULL)
  {
    printf("NULL  ");
    return;
  }
  Inorder(tr->left);
  printf("%d  ", tr->x);
  Inorder(tr->right);
}


3.后序遍历:


依旧如之前所说,改变的只是访问根的时机,所以后序遍历的方式为:左右根


也就是先访问左节点 再访问右节点,最后才访问根节点


077ad7ea88b84188b1d9b2e44e1da0d3.jpg


按照这个顺序遍历下来,其结果为:325641 可以看到根在最后


3.1后序遍历代码实现


void Postorder(tree* tr)
{
  if (tr == NULL)
  {
    printf("NULL  ");
    return;
  }
  Postorder(tr->left);
  Postorder(tr->right);
  printf("%d  ", tr->x);
}


4.前中后遍历的差别及互相转换


前序遍历 根在前


中序遍历 根在中间


后序遍历 根在最后


我们可以通过根据任意前/后+中序遍历的结果,推导出这棵树的结构

4.1前中推树的结构


8146f0a503d84c3699cb42e92edfb5ba.png


刚刚提到 前序遍历的根在第一个,而中序遍历的根在中间,


找到其所在位置,理出其左右子树


所以这颗二叉树应该是长这样的


78b731d20a7e42f8909ff646190d9e09.jpg


之后再依据刚刚的规律,通过前序的结果 发现47当中 7是根 9621当中 9是根


b8e0a86bf1f9477c843f91912831ecda.jpg


又通过中序的结果发现6是9的左子树的根  12是9的右子树 通过前序看出 2是根 1是左子树


所以这颗树就被画出来了


defe31b33fc049259f21baa40f9a08e9.jpg


可以发现 找根用前序遍历,找左右子树用中序遍历的结果

4.2中后推树的结构


中序结果为:4756912 后序结果为 4761295


依然先通过后续遍历的最后一个结果确定整棵树的根为5 然后依据中序的结果 分出左右子树


为 47 5  6912


之后再次通过刚刚的方法 与前序遍历大同小异 这里就不赘述了.


找根用后序遍历,找左右子树用中序遍历的结果

4.3前后推树的结构


这样是推不出来的 ,当这颗树只有两个节点的时候,无法分辨其为左子树还是右子树

323a4ba6878a4a768f69a89fcaae16c3.jpg


也可以得出:若前序后序刚好相反 ,其只有一个叶子节点


完结撒花:


🌈本篇博客的内容【前中后层序遍历 --二叉树的结构特点与遍历方式】已经结束。


🌈若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。


🌈若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。


🌈诸君,山顶见!

目录
相关文章
|
8月前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
272 10
 算法系列之数据结构-二叉树
|
10月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
292 12
|
10月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
190 10
|
10月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
432 3
|
11月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
10月前
|
数据采集 存储 算法
【C++数据结构——图】图的遍历(头歌教学实验平台习题) 【合集】
本文介绍了图的遍历算法,包括深度优先遍历(DFS)和广度优先遍历(BFS)。深度优先遍历通过递归方式从起始节点深入探索图,适用于寻找路径、拓扑排序等场景;广度优先遍历则按层次逐层访问节点,适合无权图最短路径和网络爬虫等应用。文中提供了C++代码示例,演示了如何实现这两种遍历方法,并附有测试用例及结果,帮助读者理解和实践图的遍历算法。
497 0
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
306 4
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
287 59
|
5月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
116 0
栈区的非法访问导致的死循环(x64)
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。

热门文章

最新文章