深度优先遍历与树的前中后序遍历

深度优先和宽度优先的区别、前(先)序遍历和中序遍历以及后序遍历的使用 深度优先 深度优先搜索属于图算法的一种 深度优先搜索是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链的HTML文件) 过程:是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次. 深度优先遍历 深度优先遍历图的方法是,从图中某顶点v出发: 从图中一个未访问的顶点V开始 沿着一条路一直走到底 第二步路走完过后,再从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底…不断递归重复2和3过程 一直执行3过程,直到所有的顶点都遍历完成(即所以顶点 阅读详情

本文主要讨论深度优先遍历与树的前中后序遍历的联系与区别,并对深度优先遍历的几种非递归实现方式进行了对比。

深度优先遍历与树的前中后序遍历的联系和区别

树的前中后序遍历是深度优先遍历应用在树结构上的一(几)种特例。我们都知道树的前序遍历的遍历顺序为:当前节点,左子树,右子树。中序遍历的遍历顺序为:左子树,当前节点,右子树。后序遍历的遍历顺序为:左子树,右子树,当前节点。(这里我使用当前节点表示当前正在处理的节点,为了跟下面深度优先遍历对应)。其实同时还有这么几种遍历方式(1)当前节点,右子树,左子树(2)右子树,当前节点,左子树(3)右子树,左子树,当前节点。这种比较不常规的遍历方式在解决某些题目的时候比较实用。


深度优先遍历通常情况下是访问当前节点,然后访问当前节点的第一个邻居(图),第二个邻居(图)……最后一个邻居(图)。之所以说是通常情况下,是因为还有非通常情况下,我们也可以先访问第一个邻居(图),然后访问当前节点,然后在访问剩下的邻居(图)。事实上,还有另外一种划分法,比如我们将当前节点的邻居根据某种属性(比如树中的左、右)或者方式化成n种邻居,那么先访问第一种邻居中的第一个,第二个,……,第二种邻居中的第一个,第二个……,访问当前节点可以插入其中任何地方。恩,就是这个意思,他们都是深度优先遍历。这里的区别主要在与邻居与当前节点的访问顺序。


这样对比起来,可以很明显的看出来,树的前中后序遍历就是深度优先遍历在树上的特例。前序遍历就对应于将邻居划分两类,先访问当前节点然后在访问邻居节点的情况。而后序遍历对应于将邻居划分为两类,先访问邻居节点然后访问当前节点的情况。中序遍历呢,就是先访问第一类邻居,然后访问当前节点,然后再访问第二类邻居。

深度优先遍历的几种非递归实现方式

我们通常实现的深度优先遍历,都是对应着树的前序遍历的一种,也就是说访问当前节点,然后再去访问它的相邻节点。我们这里讨论的是非递归实现,那么当然就会有一个用于替代递归的栈。

为了方便描述,我们将当前节点的邻居节点的入栈(进入待访问集合)的情况称作该节点的展开程度,即如果邻居节点全部入栈的话,那么叫做该节点完全展开了,否则叫做该节点非完全展开。我们从栈中存储的节点的情况来进行分类,主要有以下几种:
  1. 栈中存储的节点全部都是未访问过的。这里仍旧可以按照节点的展开程序分为两类。先说常见的第一类,完全展开。在这种情况中,访问当前节点后就立马将其出栈,然后入栈其所有的邻居节点。第二类,就是非完全展开了。在这种情况中,得有相应的数据结构支持,也就是说从当前节点,可以知道访问当前节点的父节点的第二个儿子(就是邻接表的那种结构,一个节点的所有邻居是一个链表)。访问完当前(栈顶)节点,将其出栈,然后根据当前节点找到其父节点的第二个儿子,将其入栈,然后再入栈当前节点的第一个未访问的邻居。不过感觉上,这种需要的数据结构有点奇葩。举个简单的列子,在树结构中,除了要父子节点的连接外,还要左儿子和右儿子相连接(这里不是指实际拓扑上相连,而是从左儿子可以访问到右二子)。

    非完全展开的,栈中存储的节点比较少,在节点的度比较大的时候比较有效,相反完全展开的,在度比较大的情况下,就需要很大的存储空间,尤其搜索空间再更大的时候,就比较占空间了。这个数量级大概是O(深度*度)。第一类完全展开的,使用起来比较无脑,只用push,pop就行了,不用考虑其他的。而第二类,对数据结构要求有点奇葩。这种情况,由于栈中并未存储已经访问的节点,要获得到当前的路径,并不是很方便,需要自己另开空间来记录。
  2. 栈中存储的节点,刚好是从开始节点到当前节点的一个路径。当然,它一定包含了某些已经访问的节点,并且显然节点并没有完全展开,并且只有栈顶元素是未访问过的。分析同上,这个也需要存储当前的展开位置,也就是说它的邻居节点展开到哪了,下一次该谁了亦或是没有下一个了。这种情况下,访问当前(栈顶)节点,入栈其第一个邻居,如果没有邻居或者邻居已经访问过了,那么就出栈一直到一个没有完全展开的节点,然后继续展开。好处是显而易见的,占用空间只与深度有关,并且很容易得到当前路径(比如使用vector来实现栈)。
  3. 栈中存储的节点,不仅仅包含了到当前节点的一个路径。当然每个节点是完全展开的,并且也包含了已访问过的节点。这种实现方式,通常是多余的,不过在某些访问顺序下需要这样做。在先访问,在入栈的话,貌似没有什么好处尴尬。除非要先访问邻居节点,然后再访问自己,这种就类似于后序遍历了。
那么鼎鼎大名的回溯法是属于哪种情况呢?据 这里讲

深度优先搜索法与前面讲的回溯法差不多,主要的区别是回溯法在求解过程中不保留完整的树结构,而深度优先搜索则记下完整的搜索树,搜索树起记录解路径和状态判重的作用。为了减少存储空间,在深度优先搜索中,用标志的方法记录访问过的状态,这种处理方法使得深度优先搜索法与回溯法没什么区别了。在回溯法中,我们己分析了非递归的实现过程,在这里就只讨论深度优先的递归实现方法。

好吧,他们的区别不在于栈中存储的节点。但是这个没有关系,上面也说了,为了减少存储空间,他们两个已经变的差不多了。可以认为一样吧,具体实现上就可以参考上面的三种方式了。

以上是我自己的一点拙见,欢迎讨论。
一文搞定学术英语写作 (斯坦福SCI论文写作课程笔记) 0.前言: 本文基于斯坦福Kristin Sainani 教授的学术论文写作公开课——SCI论文写作(Writing in the Sciences)。在此基础上进行章节顺序的重排及部分内容的删减,以方便第一次进行英语学术论文写作的同学快速上手。 时间充足和想要系统学习英文学术写作的同学,十分建议观看完整课程视频,一定会受益匪浅!课程地址如下: 课程B站地址:https://www.bilibili.com/video/BV1zv41177JQ 1.论... 阅读详情

相关推荐

a股level2数据接口的最优委托信息

Level-1提供的数据并不可以知道委托了xxx手是有多少人下的,以及每个人下了多少的明细。通过Level-2的这个详细买卖盘数据,盘口上的单子到底是散户小打小闹,还是主力真刀实枪在干,都一览无余。交易类型:1-市价,2-限价,3-本方优先,10-撤单, 11-暂不清楚( 基金/ 债券有此值)除了提供逐笔成交记录这个信息外,还提供了最优委托信息,也就是盘口中前50笔订单的委托数量明细。那么Level-2盘口委托数据的速度更新是非常快的,大家可以通过。交易方向:0-未知,1-买入,2-卖出。

Qq_2037696191的博客 1166

二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

目录 二叉树 概念 四种基本的遍历思想 一、前序遍历 二、中序遍历 三、后序遍历 四、层次遍历 五、深度优先遍历 六、后序遍历的简单思路 转载:二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历) 【数据结构和算法】全面剖析树的各类遍历方法 回到顶部 二叉树 概念 二叉树是一种非常重要的数据结构,非常多其他数据结构都是基于二叉树的基...

liqingtx的专栏 1162

Qwen3-Embedding选型指南:0.6B/4B/8B三版本性能对比与场景匹配建议

本文深入解析阿里开源的Qwen3-Embedding系列模型(0.6B/4B/8B)的性能差异与适用场景,提供从边缘计算到云端部署的实战选型建议。通过实测数据对比响应延迟、内存占用和多语言精度等核心指标,帮助技术团队根据业务需求选择最优模型版本,并分享边缘设备优化与云端成本测算策略。

qsc901234567的博客 892

数据结构-树与深度优先遍历

 笔者在读书时,选择的专业是计算机科学,但和大家一样,在处理线性的问题时较为熟悉,但当自己在尝试理解树和图这种非线性结构时,就总无法深刻准确的理解,为此,也很苦恼很无奈,但也没有什么好的办法。这次趁着完成了《漫画算法》的阅读,再次总结一下关于书中树的内容,也许是几年的工作经历吧,让自己对于代码的编写和理解有了更多的体会,也了解到这种非线性结构的重要性。漫画算法这本书确实生动简洁,理解起来方便,大家对于数据结构感兴趣的,可以也买这本书读读,挺有意思的。图画的形式确实能增强理解性。 概念理解 树这种结构与链表不

不当初 3140

VisionMaster位置修正功能深度解析:如何让找圆工具自动跟随移动目标?

本文深度解析海康威视VisionMaster平台的位置修正功能,重点介绍如何通过模板匹配与找圆工具的智能联动实现移动目标的动态追踪。文章详细阐述了工业视觉检测中的坐标系同步原理、模板匹配配置技巧及异常处理策略,为工程师提供了一套完整的工业级解决方案。

uu89012的博客 281

光伏逆变器在环测试解决方案

光伏行业是利用太阳能光辐射将其转化为可用电能的行业。近年来,为应对气候变化和能源安全等挑战,全球对清洁能源的需求不断增长。太阳能作为最具潜力和可再生的能源之一,被视为替代传统化石能源的重要选择,光伏行业因此得到了迅猛发展,并在全球范围内得到了广泛应用。许多国家和地区都将光伏技术作为关键的能源发展方向。尤其是在新兴和发展中国家,光伏发电具有巨大的增长潜力,将成为未来市场竞争的重点。随着规模化生产的推进,光伏组件的制造成本不断降低。

shiwei0813的博客 959

图与树的遍历:探索广度优先、深度优先及其他遍历算法的原理与实现

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 706

计算机组成原理 微程序控制器实验

微程序控制器实验 实验环境 计算机组成原理实验环境 实验目的 掌握微程序控制器的组成原理和工作过程。 理解微指令和微程序的概念,理解微指令与指令的区别与联系。 掌握指令操作码与控制存储器中微程序的对应方法。熟悉根据指令操作码从控制存储器中读出微程序的过程。 实验要求 做好实验预习,读懂实验电路图,熟悉实验元器件的功能特性和使用方法。 按照实验内容与步骤的要求,独立思考,认真仔细地完成实验。 写出实验报告。 实验电路        

Long_UP的博客 7万+

树的前/中/后序遍历(Leedcode 144、95、145) 技巧 --- 栈(深度优先遍历)

前面的话 树的前、中、后序遍历采用递归的方式都很好解决。但如果不使用递归,又该如何解决呢? 我们知道树的遍历方式有两种:深度优先遍历、广度优先遍历(层次遍历)。很显然这种前、中、后序遍历属于深度优先遍历。其实我们可以借助栈这种数据结构来实现深度优先遍历。 题目 给定一个二叉树,返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / ...

小柒的前端之旅 409

SpringBoot实战教程-springboot概论

Spring Boot 是一个快速开发框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,以及自动配置。内置web容器,帮助开发者能够实现快速开发,简化了应用系统的初始搭建以及开发过程。

鸟哥哥的专栏 4155

LDRA Testbed(TBrun)软件单元测试_操作指南

通过前面的几篇文章,使用Testbed进行软件静态分析的内容已经基本讲解完毕。从这篇文章开始,将继续讲解如何使用TBrun进行软件单元测试、软件集成测试。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 7766

tinyxml2遍历所有节点_数据结构与算法-二叉树遍历

树的遍历是当且仅当访问树中每个节点一次的过程。遍历可以解释为把所有的节点放在一条线上,或者将树线性化。遍历的定义只指定了一个条件:每个节点仅访问一次,没有指定这些节点的访问顺序。因此,节点有多少种排列方式,就有多少种遍历方法。对于有n个节点的树,共有n!个不同的遍历方式。然而大多数遍历方式是混乱的,很难从中找到规律,因此实现这样的遍历缺乏普遍性。经过前人总结,这里介绍两种遍历方式,即广度优先遍历与...

weixin_39545310的博客 537

信号处理算法:离散余弦变换(DCT)_(1).离散余弦变换(DCT)概述

离散余弦变换的数学定义如下:对于一个长度为NNN的离散信号xnx(n)xn,其DCT变换后的系数XkX(k)XkXk∑n0N−1xncos⁡πNn12kk012N−1Xkn0∑N−1​xncosNπ​n21​kk012N−1其中,kkk是频率指数,nnn是时间或空间索引。离散余弦变换(DCT)是一种强大的信号处理技术,广泛应用于图像压缩、音频处理、数据压缩等领域。

2401_87715305的博客 1554

树遍历(BFS+DFS(递归+非递归))-python代码整理

数据结构算法-树 最近再刷leetcode的树,整理了常用遍历代码 包含树的层次遍历(广度优先遍历)与前中后序遍历(深度优先遍历): ######################################### 层次遍历(广度优先遍历)★★★★★ #BFS通用模板,层次遍历通用: #使用队列实现 def levelOrder(root): if not root: return [] queue=[root] ans=[] while queue: a=[] #方便保存每一层的

weixin_45469590的博客 1612

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

算法通过村第六关-树青铜笔记|中序后序

算法笔记;树的概念和性质;二叉树的扩展;前中后续序列;树的恢复;

weixin_46585492的博客 307

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

数据结构与算法1:二叉树(binary_tree)的前、中、后序(深度优先)和广度优先遍历及python代码实现

目录二叉树的前中后序遍历定义用递归的方法创建树和遍历树 二叉树的前中后序遍历定义 树(英语:Tree)是一种无向图(undirected graph),其中任意两个顶点间存在唯一一条路径。或者说,只要没有回路的连通图就是树 二叉树(英语:Binary tree)是每个节点最多只有两个分支(不存在分支度大于2的节点) 的树结构。通常分支被称作“左子树”和“右子树”。二叉树的分支具有左右次序,不能...

王远的博客 710

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

树

深度优先遍历前中后序递归非递归遍历 广度优先遍历 层次遍历 求树的深度 树的层数

qq_43252908的博客 134

算法学习笔记——理解树的结构

int val;这里本质上就是有两个引用,分别指向两个位置,为了便于理解,我们分别命名为左孩子和右孩子。如果是N叉树该如何定义呢?int val;能否用数组来存储二叉树呢?其实就是用数组来存储二叉树,顺序存储的方式如图:用数组来存储二叉树如何遍历的呢?如果父节点的数组下表是i,那么它的左孩子就是i * 2 + 1,右孩子就是 i * 2 + 2。但是用链式表示的二叉树,更有利于我们理解,所以一般我们都是用链式存储二叉树。所以大家要了解,用数组依然可以表示二叉树。

xuanyue_18的博客 211

代码随想录算法训练营第十四天| 理论基础 递归遍历 迭代遍历 统一迭代

注意要写constructor。用initializer list。1. 默写treeNode。2. 遍历顺序及对应方法。

amytheace的博客 231

代码随想录第十六天| 513.找树左下角的值 、112. 路径总和 、113. 路径总和 II、106、从中序与后序遍历序列构造二叉树

判断该树中是否存在一条从根节点到叶子节点的路径,使得路径上所有节点值的和等于目标和。,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。给定一个二叉树,找到树的最后一行最左边的节点值。:根据一棵树的中序遍历与后序遍历构造二叉树。:根据一棵树的中序遍历与前序遍历构造二叉树。:你可以假设树中没有重复的元素。:你可以假设树中没有重复的元素。给定一个二叉树和一个目标和。

Sweeping_Robot的博客 404

【代码随想录】Day 14 二叉树基础(前中后序遍历)

int val;

weixin_43785314的博客 127

C++实现树的前中后序遍历、广度、深度优先遍历、求叶子结点、一度、二度结点数量、判断是否是完全、满二叉树、交换左右结点、求解所有根结点到树叶的路径、求最大宽度、高度、树深、求最长路径、输出所有叶子结点

先上传,有时间再改逻辑 /* 测试树: ABC00DE0G00F00H.. ABS00C00DE00FG0H00I00 ABD00E00CF000 完全二叉树 ABD00E00CF00G00满二叉树 abcd00e00f00ig00h00 abd00e00cf00g00 */ #include<iostream> #include<stack> #include<queue> #define OK 1 #define maxsize 100 using .

galaxyrt的博客 1031

代码随想录刷题|二叉树的理论基础、 二叉树的遍历 LeetCode 144、145、94、120

二叉树的理论基础、 二叉树的遍历

symdunstaz的博客 189

力扣记录:二叉树2二叉树的属性(4)——112 路径总和及相关题目,404 左叶子之和,513 找树左下角的值

力扣记录:二叉树2二叉树的属性(4)——112 路径总和及相关题目,404 左叶子之和,513 找树左下角的值

Kiwi_fruit的博客 337

(数据结构初阶)二叉树 (二)

目录一 树的链式存储结构二 树的链式结构简单实现1.基本结构2.结点创建3.前中后序遍历为深度优先遍历,层序遍历为广度优先遍历4.求结点个数5.求叶子结点个数6.求第K层结点个数7.查找树里面值为x的那个结点8.销毁树9.判断一棵树是不是完全二叉树三 完整文件1.BinaryTree.h2.BinaryTree.c3.test.c1.四种遍历顺序:前序遍历(先根)、中序遍历(中根)、后序遍历(后根)、层序遍历。2.递归:①子问题。②结束条件。3.排序二叉树:①又称二叉搜索树,它的左孩子都小于父亲,右孩子都大

qq_57594025的博客 253

python第十六课 高级 树的实现

# 非递归遍历实现(使用栈结构) class BinaryTree: # ...(保留原有方法) # 非递归前序遍历 def preorder_stack(self, root): stack = [] while root or stack: while root: print(root.item, end=' ') # 访问根节点 stack.append(root) root = root.lchild # 访问左子树 if stack: root = stack.pop() root = root.

hsjshsft的博客 714
上一篇: 经典排序算法2-堆排序及优先队列
下一篇: 虚函数:从入门到精通
binary_search
博客等级 码龄14年 6粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值