递归实现 前/中/后序 遍历二叉树 的详细讲解

news/2024/9/23 11:50:36/

一:要遍历的二叉树模型

例子是博主随意创建的二叉树,可自己更改

二:手动构建二叉树模型

1:单个节点结构体的定义

解释:

一个节点应该有值val,还有两个指针指向它的左右孩子。

2:创建节点函数 

解释:

此函数创建了一个节点,并且进行了初始化。

3:手动构建二叉树模型 

解:

a:根据模型已知:

共六个节点

值为1的节点左孩子为2,右孩子为4

值为2的节点左孩子为3,无右孩子

值为3的节点无孩子

值为4的节点左孩子为5,右孩子为6

值为5 ,6 的节点,无孩子

b:所以BuyNode函数创建了6个节点,再根据a的信息进行left和right的连接,无孩子即为NULL。在BuyNode函数内部已经初始化为NULL,不需要在这里再额外的置空。

三:前序遍历

模型:

前序遍历效果:

解释:

二叉树的前序遍历(Pre-order Traversal)是一种遍历二叉树节点的算法。在前序遍历中,访问节点的顺序是:

  1. 访问根节点:首先访问二叉树的根节点。
  2. 前序遍历左子树:然后递归地前序遍历根节点的左子树。
  3. 前序遍历右子树:最后递归地前序遍历根节点的右子树。

简单来说,前序遍历的顺序是:根节点 -> 左子树 -> 右子树。

所以前序遍历的结果是:1 ->2 -> 3 -> 4 -> 5 -> 6

这个过程可以这样理解:

  1. 访问节点1(根节点)。(1)
  2. 递归地遍历左子树:访问节点 2,(1 2)然后递归地遍历 2的左子树(访问节点 3)(1 2 3),接着遍历2的右子树(NULL,所以跳过)。
  3. 递归地遍历右子树:访问节点 4(1 2 3 4),然后递归地遍历 4 的左子树(访问节点 5)(1 2 3 4 5),接着遍历 4 的右子树(访问节点 6)(1 2 3 4 5 6)

递归实现前序遍历函数:

递归的路线:

(红色代表递,蓝色代表归)

不太清晰,分左右发

左: 

右:

 

可以看出,打印这个步骤是最先的 ,都是在左右子树遍历前。

四:中序遍历 

 

 中序遍历效果:

 解释:

二叉树的中序遍历(In-order Traversal)是另一种遍历二叉树节点的算法。在中序遍历中,访问节点的顺序是:

  1. 中序遍历左子树:首先递归地中序遍历根节点的左子树。
  2. 访问根节点:然后访问根节点。
  3. 中序遍历右子树:最后递归地中序遍历根节点的右子树。

简单来说,中序遍历的顺序是:左子树 -> 根节点 -> 右子树。

中序遍历的结果是:3-> 2 ->1 -> 5 -> 4 -> 6

这个过程可以这样理解:

  1. 递归地遍历左子树:访问节点 2 的左子树,即节点 3。(3)
  2. 访问节点 2。(3 2)
  3. 继续递归地遍历 2 的右子树,(这里为空,所以跳过)。
  4. 回到根节点 1,访问节点1。(3 2 1)
  5. 递归地遍历右子树:访问节点 4 的左子树,即节点 5(3 2 1 5)
  6. 访问节点4(3 2 1 5 4)
  7. 访问节点 4 的右子树,即节点 6(3 2 1 5 4 6)

 递归实现中序遍历函数:

 递归的路线:

左:

右:

 可以看出,打印这个步骤是次先的 ,都是在左子树走完之后

五:后序遍历 

模型:

后序遍历效果:

二叉树的后序遍历(Post-order Traversal)是遍历二叉树节点的另一种算法。在后序遍历中,访问节点的顺序是:

  1. 后序遍历左子树:首先递归地后序遍历根节点的左子树。
  2. 后序遍历右子树:然后递归地后序遍历根节点的右子树。
  3. 访问根节点:最后访问根节点。

简单来说,后序遍历的顺序是:左子树 -> 右子树 -> 根节点。

后序遍历的结果是:3 -> 2-> 5 -> 6 ->4 -> 1

这个过程可以这样理解:

  1. 递归地遍历左子树:首先访问节点 2 的左子树,即节点 3。(3)
  2. 继续递归地遍历 2 的右子树,(这里为空,所以跳过)。
  3. 访问节点 2。(3 2)
  4. 递归地遍历右子树:首先访问节点 4 的左子树,即节点 5,然后递归地遍历,4 的右子树,即节点 6。(3 2 5 6)
  5. 访问节点 4。(3 2 5 6 4)
  6. 最后访问根节点 1。(3 2 5 6 4 1)

 递归实现后序遍历函数:

 递归的路线:

左:

右:

 

 可以看出,打印这个步骤是最后的 ,都是在左右子树走完之后 

 

 总结:

三种遍历二叉树的方法——前序遍历中序遍历后序遍历——的主要区别在于访问根节点的时机不同。

 

 

 

 


http://www.ppmy.cn/news/1512635.html

相关文章

11.怎么做好一个动态标签页

效果 步骤 1.在Elementui找一个标签页组件 复制粘贴到代码 2.将他写活 将很多页面需要用的方法和变量写入store editableTabsValue: 2,editableTabs: [{title: 首页,name: index,},],addTab(state, tab) {if (state.editableTabs.findIndex(item > item.title tab.titl…

强制 Vue 重新渲染组件的5种方法

使用 key 强制重新渲染 key 属性是 Vue.js 中一个重要的特性&#xff0c;它用于标识虚拟 DOM 元素。当 key 发生变化时&#xff0c;Vue 会认为是一个新的元素&#xff0c;从而触发重新渲染。 示例 <template><div><button click"forceRerender">…

go语言递归、分解处理任务

前言 Go 语言中&#xff0c;可以用递归来分解主任务。假设你要处理一个包含多个任务的列表&#xff0c;可以将每个任务递归地分解为更小的任务。 一、创建子任务 // 创建任务及子任务task1 : &Task{Name: "Task 1"}task2 : &Task{Name: "Task 2"…

73、 dockerfile

一、dockerfile 自定义镜像---------通过docker创建镜像。 1.1、创建镜像的方式&#xff1a; 1、dockerfile最基的方式&#xff0c;最常用的方式。 2、docker pull 拉取的是最基础的镜像&#xff0c;只有基础功能&#xff0c;没有定制化的功能。 3、基于基础镜像&#xff…

【JavaEE初阶】TCP协议

&#x1f332;TCP协议的概念 TCP&#xff08;TransmissionControlProtocol 传输控制协议&#xff09;是一种面向连接的、可靠的、面向字节流&#xff0c;双全工的传输层通信协议。 这几个特点在我们前面写得TCP服务器和客户端的搭建中&#xff0c;代码能够直观的感受到&#…

Maven 从本地文件系统加载依赖项

使用了 <scope>system</scope> 来指定一个依赖项 指定了 <systemPath> 属性来指向本地文件系统中的 JAR 文件 关于 <scope>system</scope> 和 <systemPath>: <scope>system</scope>: 这个 scope 表示该依赖项是在系统的类路径…

团队管理之敏捷开发

一、敏捷实践 敏捷开发中一直秉承的理念和宣言是&#xff1a;我们正在通过亲身实践以及帮助他人实践&#xff0c;揭示更好的软件开发方法。通过这项工作&#xff0c;我们认为&#xff1a;个体和交互胜过过程和工具、可以工作的软件胜过面面俱到的文档、客户合作胜过合同谈判、…

SpringBoot获取不到Nacos配置信息报错,Nacos鉴权

重启生产环境项目报错&#xff0c;某某配置找不到&#xff0c;检查了配置文件&#xff0c;配置没有被改动过&#xff0c;也没有加新的配置。服务打包也没有问题。 检查连接Nacos的配置项时&#xff0c;突然想起前段时间升级Nacos&#xff0c;开启了鉴权&#xff0c;是不是跟这个…