首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

用递归的思想实现二叉树前、中、后序迭代遍历

先复习一下前、中、后遍历的顺序: 前序遍历顺序:中-左-右 中序遍历顺序:左-中-右 后序遍历顺序:左-右-中 用递归来写二叉树遍历是非常简单的,例如前序遍历的代码如下: const result =...理解了递归调用栈的情况,再来看看怎么利用递归思想实现前序迭代遍历: function preorderTraversal(root) { const result = [] // 用一个数组...// 当前 node 节点的上一个节点必定是它的父亲节点 // 前序遍历是中-左-右,现在左子树已经到头了,该遍历父节点的右子树了 // 所以要弹出父节点...弹出节点 4 并从它的右子节点开始新的循环 由于节点 4 的右子节点为空,所以不会进入 while 循环,然后弹出节点 4 的父节点 2 再从节点 2 的右子节点开始循环 看到这是不是已经发现了这个迭代遍历的过程和递归遍历的过程一模一样...而且用递归的思想来实现迭代遍历,优点在于好理解,以后再遇到这种问题马上就能想起来怎么做了。 中序遍历 中序遍历和前序遍历差不多,区别在于节点出栈时,才将节点的值推入到 result 中。

84650

二叉树详解(深度优先遍历、前序,中序,后序、广度优先遍历、二叉树所有节点的个数、叶节点的个数)

节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。...}; 另一种方式:顺序表存孩子的指针(不推荐使用) struct TreeNode { int data; vector<struct TreeNode*...); // 递归遍历右子树 PostOrder(root->right); // 访问当前节点的数据 printf("%c ", root->data); } 4.4二叉树所有节点的个数...//方法一:定义全局变量(不推荐) // 全局变量,用于记录树的大小(节点数) // 注意:使用全局变量通常不是好的做法,应该尽量避免 int size = 0; // 计算二叉树的大小...TreeSize(root->right); } 4.7层序遍历(广度优先遍历,使用队列) 这是使用的队列的代码 //队列初始化 void QueueInit(Queue* pq) { assert

3K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【二叉树进阶】二叉树的前中后序遍历(非递归迭代实现)

    二叉树的前序遍历 题目链接: link 不用递归,用迭代算法如何实现对二叉树的前序遍历? 最终放到一个vector里面返回。...1.1 思路分析 前序遍历的非递归呢我们可以这样来搞: 题目中给的二叉树比较简单,下面通过这样一棵二叉树给大家讲解: 对它进行非递归的前序遍历,它是这样搞的: 前序遍历是根、左子树、右子树...二叉树的中序遍历 题目链接: link 接下来我们就来看一下二叉树中序遍历的非递归如何实现 2.1 思路分析 其实大体的思路还是跟上一道题的差不多,最后写出来跟上一题的代码也基本一样,其中一句代码换一下位置就行了...二叉树的后序遍历 题目链接: link 那后序遍历的非递归又如何实现呢? 这里提供两种思路 3.1 思路1 思路1呢是这样的: 大家想前序是根、左子树、右子树。...而不是用刚才这种取巧的方法: 后序遍历是左子树、右子树、根; 而中序遍历是左子树、根、右子树 所以,后序遍历前面的操作和中序是一样的: 还是先让左路结点入栈 然后对于栈顶的元素我们可以直接让它入

    27110

    总结了一些算法二叉树操作的干货 (附Python代码)

    这里的前中后序实际上是指根节点相对左右子节点的位置来描述的,如前序遍历就是指根节点在左右节点之前,中序则是根节点在左右子节点之间,后序则是根节点在最后。 ?...只要稍微更改主程序中递归调用的先后顺序,即可很容易改写成其他遍历方式。...用递归可以实现的操作,一般来说迭代也可以,二叉树的遍历也不例外。 为了实现DFS遍历,那么一般要用到栈的数据结构。...,因为是,需要用到两层嵌套循环,相当于对每一个节点,都首先要进行压栈操作直至将其所有左子节点部分都遍历完成才处理当前节点,理解起来会有点绕 class Solution: def inorderTraversal...在迭代写法中,首先遍历整个树构建每个节点的前溯节点,进而根据两个节点的前溯节点反向对比,直至找到第一个公共节点。

    32120

    数据结构与算法的框架思维

    线性就是 for/while 迭代为代表,非线性就是递归为代表。再具体一步,无非以下几种框架:1....链表遍历框架,兼具迭代和递归结构:// 基本的单链表节点class ListNode { int val; ListNode next;}void traverse(ListNode head...二叉树遍历框架,典型的非线性递归遍历结构:// 基本的二叉树节点class TreeNode { int val; TreeNode left, right;}void traverse(TreeNode...即避免所有冗余的计算,消耗尽可能少的资源求出答案。什么算法的难点在「如何穷举」呢?一般是递归类问题,比方说回溯算法、动态规划系列算法。...你用嵌套 for 循环花 O(N^2) 的时间肯定可以穷举出所有子数组,也就必然可以找到符合题目要求的子数组。

    12910

    boltdb源码分析系列-Bucket

    rootNode是这颗B+Tree的根节点node. 只要知道了树的根节点,就可以从根节点遍历获取所有的其他节点。...在boltdb源码分析系列-内存结构文章中node结构定义中可以看到,它是一个递归的定义,node节点中的children记录它的孩子节点。所以Bucket只要记录根节点,便拥有了整颗树的信息。...Bucket 查找Bucket过程如下: 先查找缓存,Bucket对象中的map会记录它里面子Bucket信息,如果缓存中有,直接返回 遍历Bucket查找,需要先创建一个Bucket迭代器(Cursor...= nil { return child } } // 创建一个游标对象,用于对bucket进行遍历 c := b.Cursor() // 在B+树中查找key为name的节点 k...,只是在当前桶中查找,并不会递归查找子桶,整个查找过程是通过迭代器完成的,迭代器工作方法在下一篇文章中详细介绍。

    1.7K10

    写给小白的开源编译器

    AST 是一个深度嵌套的对象,用一种更容易处理的方式代表了代码本身,也能给我们更多信息。...LETTERS.test(char)) { let value = ''; // 同样,我们遍历所有,并将它们完整的存到`value`变量中 while (LETTERS.test(char...由于我们的目标是一种新的语言,所以我们将要专注于创造一个完全新的 AST 来配合这个特定的语言。 为了能够访问所有这些节点,我们需要遍历它们,使用的是深度遍历的方法。...但是仅仅访问树中的每个节点对于我们来说想做和能做的事情已经很多了。 (使用访问(visiting)这个词是因为这是一种模式,代表在对象结构内对元素进行操作。)...虽然我们并不会常常与 AST 直接打交道,但它总是无时无刻不陪伴着我们。 当然啦!看完文章不一定算真正了解了,所有学习过程都离不开动手实践,或许实践过程中你也会有不一样的理解。

    75010

    来来来,我们聊一聊,为什么不建议使用递归操作?

    递归的问题 如题,我们可能或多或少的都听见过类似的话或者建议: 尽量少使用递归操作,甚至干脆就不要使用递归操作。 但我们在听到这句话的时候,是否会产生过疑问,为什么不建议使用递归操作呢?...我们知道,Java 源代码需要编译成字节码文件,然后由 JVM 解释执行,为了能高效地管理程序方法的调用,有条不紊地进行嵌套的方法调用和方法返回,JVM 维护了一个栈结构,称为虚拟机方法栈(如果调用的是...在 JVM 中,方法调用的过程大致为: 除非被调用的方法是类方法,否则在每一次方法调用指令之前,JVM 会先把方法被调用的对象引用压入操作数栈中,除了对象的引用之外,JVM 还会把方法的参数依次压入操作数栈...但对于某些问题,如上面我们考虑的二叉树的中序遍历,在条件允许的情况下,我们还是倾向于使用递归实现的,因为相对来说,递归的实现更简单,也更容易理解。...,由于中序遍历的顺序为首先遍历左子树、然后访问根结点、最后遍历右子树,因此我们从根节点开始,依次将左节点压入栈,直至把左子树遍历完,然后再依次弹栈,并将弹出的节点值存入我们设置的结果列表ans,最后再将当前节点的右节点赋值给当前节点

    1K00

    正则表达式嵌套匹配

    1、问题背景给定一个包含嵌套标记的字符串,如果该字符串满足XML格式,希望提取所有嵌套的标记和它们之间的内容,并将提取信息作为一个字典输出。...XML解析器XML解析器可以将XML文档解析成一个DOM树(文档对象模型),然后通过递归算法遍历DOM树,提取嵌套标记和它们之间的内容,最后将提取信息作为一个字典输出。...因此,需要使用一些技巧来实现嵌套标记的匹配。(3)使用递归函数递归函数是一种能够自我调用的函数。可以使用递归函数来实现嵌套标记的匹配。...递归函数的基本思想是:将大问题分解成小问题,然后不断地迭代求解小问题,直到最终得到问题的解。...ET.fromstring(string) # 使用递归算法遍历DOM树,提取嵌套标记和它们之间的内容 result = {} def traverse(node, tag_ids): #

    53710

    来来来,我们聊一聊,为什么不建议使用递归操作?

    但我们在听到这句话的时候,是否会产生过疑问,为什么不建议使用递归操作呢? 现在,我们就一起聊聊这个话题,看看递归到底会产生什么样的问题。 首先,我们思考一道算法题:如何实现二叉树的中序遍历?...我们知道,Java 源代码需要编译成字节码文件,然后由 JVM 解释执行,为了能高效地管理程序方法的调用,有条不紊地进行嵌套的方法调用和方法返回,JVM 维护了一个栈结构,称为虚拟机方法栈(如果调用的是...在 JVM 中,方法调用的过程大致为: 除非被调用的方法是类方法,否则在每一次方法调用指令之前,JVM 会先把方法被调用的对象引用压入操作数栈中,除了对象的引用之外,JVM 还会把方法的参数依次压入操作数栈...但对于某些问题,如上面我们考虑的二叉树的中序遍历,在条件允许的情况下,我们还是倾向于使用递归实现的,因为相对来说,递归的实现更简单,也更容易理解。...,由于中序遍历的顺序为首先遍历左子树、然后访问根结点、最后遍历右子树,因此我们从根节点开始,依次将左节点压入栈,直至把左子树遍历完,然后再依次弹栈,并将弹出的节点值存入我们设置的结果列表ans,最后再将当前节点的右节点赋值给当前节点

    48720

    JavaScript数据结构(4):树

    您正在阅读的段落表示为元素中的文本;元素嵌套在元素中;元素嵌套在元素中。 这些嵌套数据和家族数类似。...使用recurse的注释中提到的步骤,我将描述递归用来recurse整个树的一般过程。 这里是步骤: 立即使用树的根节点作为其参数调用recurse。 此时,currentNode指向当前节点。...进入for循环并且从第一个子节点开始,每一个子节点都迭代一次currentNode函数。 在for循环体内,使用currentNode的子元素调用递归。 确切的子节点取决于当前for循环的当前迭代。...以下示例演示如何使用traverseDF(callback)遍历树。要遍历树,我将在下面的示例中创建一个。我现在使用的方法不是罪理想的,但它能很好的工作。...想象一下,我们要将包含奇数数据的任何节点记录到控制台,并使用BFS遍历树中的每个节点。

    57510

    使用C# (.NET Core) 实现组合设计模式 (Composite Pattern)

    我们需要一种类似树形的结构, 让其可以容纳/适应菜单, 子菜单以及菜单项. 我们还需要维护一种可以在该结构下遍历所有菜单的方法, 要和使用遍历器一样简单....针对需求我们可以创建出一种树形结构, 它可以把嵌套的菜单或菜单项在相同的结构下进行处理. 组合和单个对象是指什么呢?...客户Client, 使用Component来操作组合中的对象. Component定义了所有对象的接口, 包括组合节点与叶子....客户可以对某种类型的节点做出毫无意义的操作, 当然了, 这也是设计的决定. 组合迭代器 服务员现在想打印所有的菜单, 或者打印出所有的素食菜单项. 这里我们就需要实现组合迭代器....请仔细看下面这个组合迭代器(遍历器)的代码, 一定要弄明白, 这里面就是递归, 递归: using System; using System.Collections; using System.Collections.Generic

    1.1K00

    C#如何遍历某个文件夹中的所有子文件和子文件夹(循环递归遍历多层),得到所有的文件名,存储在数组列表中

    D:\\test"; List nameList = new List(); Director(path,nameList); 响应(调用)代码如上面,比如写在某个事件中。...首先是有一个已知的路径,现在要遍历该路径下的所有文件及文件夹,因此定义了一个列表,用于存放遍历到的文件名。...递归遍历如下:将已知路径和列表数组作为参数传递, public void Director(string dir,List list) { DirectoryInfo d...} //获取子文件夹内的文件列表,递归遍历 foreach (DirectoryInfo dd in directs) { Director...(dd.FullName, list); } } 这样就得到了一个列表,其中存储了所有的文件名,如果要对某一个文件进行操作,可以循环查找: foreach (string fileName

    15.4K40

    总结了一些二叉树操作的干货……

    这里的前中后序实际上是指根节点相对左右子节点的位置来描述的,如前序遍历就是指根节点在左右节点之前,中序则是根节点在左右子节点之间,后序则是根节点在最后。 ?...只要稍微更改主程序中递归调用的先后顺序,即可很容易改写成其他遍历方式。...用递归可以实现的操作,一般来说迭代也可以,二叉树的遍历也不例外。 为了实现DFS遍历,那么一般要用到栈的数据结构。...,因为是,需要用到两层嵌套循环,相当于对每一个节点,都首先要进行压栈操作直至将其所有左子节点部分都遍历完成才处理当前节点,理解起来会有点绕 class Solution: def inorderTraversal...在迭代写法中,首先遍历整个树构建每个节点的前溯节点,进而根据两个节点的前溯节点反向对比,直至找到第一个公共节点。

    30610

    接着讲递归遍历

    递归遍历 递归的另一个重要应用是递归遍历。 想象一下,我们有一家公司。...迭代的方法并不容易,因为结构并不简单。第一个想法可能是在公司上创建一个for循环,在第一级部门上嵌套子循环。...但是,我们需要更多嵌套的子循环来迭代第二级部门(如站点)的员工……然后在那些第三级部门中再出现一个子循环,将来会出现吗?如果我们在代码中放置3-4个嵌套的子循环来遍历单个对象,它就会变得相当丑陋。...这就是递归的力量。它也适用于任何层次的子部门嵌套。 下面是调用的图表: ? 我们很容易看到这个原则:对于一个对象{…}子调用,而数组是递归树的“叶”,它们给出直接的结果。...注意,代码使用了我们之前介绍过的智能特性: 加勒比海盗的方法。reduce在Array方法中解释了获取数组和的方法。

    52920

    通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化,reduce()的使用详解(附实际应用代码)

    将嵌套的对象结构扁平化,便于后续处理。...// 将嵌套的对象结构扁平化,便于后续处理。...reduce嵌套,为了规避双层对象嵌套,将内层的累加起始值设置为外层累加器 // 就能实现内层键值对均累加到外层累加器中,实现双层reduce嵌套结果为单层对象的效果 const flattenedData...[{ id: 7, parent: 6, children: [] }] } ] 1.3.7、性能优化 在某些情况下,array.reduce()可以用于优化性能,因为它允许在单一的遍历中完成复杂的操作...// 在某些情况下,reduce() 可以用于优化性能,因为它允许在单一的遍历中完成复杂的操作,减少了迭代次数。

    27310

    【Groovy】集合遍历 ( 使用集合的 findAll 方法查找集合中符合匹配条件的所有元素 | 代码示例 )

    文章目录 一、使用集合的 findAll 方法查找集合中符合匹配条件的所有元素 1、闭包中使用 == 作为 findAll 方法的查找匹配条件 2、闭包中使用 is 作为 findAll 方法的查找匹配条件...3、闭包中使用 true 作为 findAll 方法的查找匹配条件 二、完整代码示例 一、使用集合的 findAll 方法查找集合中符合匹配条件的所有元素 ---- 在上一篇博客 【Groovy】集合遍历...方法 , 获取集合中第一个符合 闭包匹配条件的元素 ; 使用集合的 findAll 方法 , 可以 获取 集合 中 所有 符合 闭包匹配条件的元素 , 这些元素将使用一个新的集合盛放 , findAll...is 作为 findAll 方法的查找匹配条件 在集合的 findAll 方法中 , 闭包中使用 is 作为查找匹配条件 , 查找集合中与 “3” 对象相同地址的元素 , 此处的 is 方法等价于调用...闭包中使用 is 作为查找匹配条件 findCollectionResult = list.findAll{ // 查找集合中与 "3" 对象相同地址的元素

    3K30

    题目不让我做什么,我就偏要去做什么🤔

    注意,这个列表里面装着的是NestedInteger,也就是说这个列表中的每一个元素可能是个整数,可能又是个列表,这样无限递归嵌套下去…… NestedInteger有如下 API: public class...NestedInteger结构可以无限嵌套,怎么把这个结构「打平」,为迭代器的调用者屏蔽底层细节,扁平化地输出所有整数元素呢?...我把所有叶子节点都拿出来,不就可以作为迭代器进行遍历了吗? N 叉树的遍历怎么整?...我们的解法中,一次性算出了所有叶子节点的值,全部装到result列表,也就是内存中,next和hasNext方法只是在对result列表做迭代。...如果想做到这一点,使用递归函数进行 DFS 遍历肯定是不行的,而且我们其实只关心「叶子节点」,所以传统的 BFS 算法也不行。

    77020

    值得收藏!16段代码入门Python循环语句

    01 for for循环是迭代循环,在Python中相当于一个通用的序列迭代器,可以遍历任何有序序列,如str、list、tuple等,也可以遍历任何可迭代对象,如dict。...不同于C语言,Python中的for语句将遍历系列中的所有成员,遍历顺序为成员在系列中的顺序。需要注意,在for循环中改变任何序列的内容都是危险的!...通过代码清单5和代码清单6可以看到,灵活地利用递归式,可以实现程序流向的控制。 while循环同样可以使用嵌套,嵌套的while循环实现成绩录入系统如代码清单7所示。...使用列表推导式时,需要将推导式写在[]中。list中的元素可以来源于其他类型序列、可迭代对象或自建的满足一定条件的序列。使用列表推导式的好处是代码更加简洁,实现效率更高。...从环境配置、基本语法、基础函数到第三方库的安装与使用,对各个操作步骤、函数、工具、代码示例等的讲解非常详尽,确保所有满足条件的读者都能快速入门。

    3K20
    领券