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

面试中很值得聊的二叉树遍历方法——Morris遍历

普通的非递归和递归方法的额外空间和树的高度有关,递归的过程涉及到系统压栈,非递归需要自己申请栈空间,都具有O(N)的额外空间复杂度。 Morri遍历的原则: 1. 假设当前节点为cur, 2....【2】 20 21 } 22 } ​ 所有节点遍历左子树右边界的时间总代价O(N) 基于Morris的先中后序遍历 如果cur有左子树一定能遍历2次,没有左子树只能遍历一次。...9 } ​ (3)在Morris遍历中按时机打印。 ​...23 printRightEdge(head); 24 } Morris遍历的应用 如何判断一棵树是否是搜索二叉树?...什么时候用树型DP什么时候用Morris遍历? 当必须得到左树的信息和右树的信息后,再在当前节点整合二者信息后做出判断则用树型DP是最优解。

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

    一文横扫二叉树的所有遍历方法

    关于二叉树遍历的定义中有两个关键词:次序和访问。 二叉树的遍历次序不同于线性结构,线性结构最多也就是分为顺序、循环、双向等简单的遍历方式。...,我们已知后序遍历的节点访问顺序为:左 → 右 → 中;我们将这个次序颠倒过来:中 → 右 → 左;有没有想到前序遍历的节点访问顺序呢?...(取巧的方法的动画在上面的视频中) 紧接着看代码,你绝对会有种豁然开朗的感觉,注意要逆序输出,只需要每次在链表的头部插入元素即可,此外,由于栈本身的特性,对于 中 → 右 → 左 ,我们应该现将左子节点入栈...层序遍历 若树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。...总结 二叉树的遍历包含四中遍历方法:前序遍历(中 → 左 → 右)、中序遍历(左 → 中 → 右)、后序遍历(左 → 右 → 中)和层序遍历。

    64930

    为什么说二叉树遍历用递归的方法不如非递归方法?

    非递归的方法是用存储代替计算,就是在建立树时,实现了存储展开,相当于存储了未来需要遍历的路径,所以就快了。...二叉树遍历在数据结构中用得多,这种算法是从kb时代的内存来的,主要用于理解概念,提升编程时的思想用。 实际用途中如果用于商业一般用数据库代替,根本用不到二叉树,是用存储代替计算。...速度快,可以用内存数据库,如我用h2 database的Memory Mode 在java下可以实现1秒1百万次插入。用sqlite内存模式代替以前在c++需要手工管理的数据结构。...对于树结构,可以在数据库中存储一棵树。实际上数据库的存储多用树,如B树、B-树、B+树、B*树。...当然如果你写加密算法,这种要求极高的程序时,还是需要考虑性能最大化的,否则一般用存储代替遍历计算,因为内存和硬盘,现在很便宜了,而cpu还是一种宝贵的资源。

    1K20

    二叉树遍历基础 -- 递归与非递归的实现方法

    之前也写过不少关于二叉树的东西了,但是总体来说,二叉树还是一个很绕的东西,所以单独择出来写一篇笔记,之前也没计划什么的,就想到什么写什么吧。...不过该篇文章的主要内容是关于二叉树的三种遍历(前序、中序、后序)不同的实现方式(递归与非递归)。 首先,我觉得很有必要去彻底理解一下递归。...个人认为,可以用循环实现的,递归基本上都可以实现,但有时递归的效率不如循环。 (3)递归又分为单递归与多递归(二叉树的三种遍历递归方法均用到了双递归!)...二叉树的三种遍历:前序(根左右)、中序(左根右)、后序(左右根) ? 首先看三种遍历的递归实现方法。...关键点:如果打印在递归后面,则递归是不受打印影响的,也就是,我递归要先执行完,才开始执行你打印,但是如果打印在递归前面,相当于打印已经属于这个递归体了,没次递归的时候都要执行一次打印!!!

    92410

    Python|二叉树的遍历问题解决方法

    问题描述 二叉树是由n个结点的有限集合,该集合或者为空集,或者由一个根节点和两颗互不相交的、分别称为根节点的左子树和右子树的二叉树组成。...二叉树特征:每个结点最多只有两颗子树,即二叉树中结点的度最高不能超过2个,子树的左右顺序不能颠倒。...解决方案 遍历的口诀: 先序遍历,即先根再左再右; 中序遍历:即先左再根再右; 后序遍历:即先左再右再根 二叉树层次遍历问题Python代码 void level(BTNode *p){ int...= NULL) { rear = (rear + 1)%maxsize; } } }} 结语 本文描述了二叉树的定义和特征...,并归纳了二叉树的遍历算法,总的来说二叉树的遍历只要记住口诀就挺好做的,难点在于它的python代码,我们这方面的知识点比较欠缺,希望在以后的学习中能逐渐突破自己。

    33220

    Java 实现二叉树的构建以及3种遍历方法

    转载自http://ocaicai.iteye.com/blog/1047397 大二下学期学习数据结构的时候用C介绍过二叉树,但是当时热衷于java就没有怎么鸟二叉树,但是对二叉树的构建及遍历一直耿耿于怀...目录:  1.把一个数组的值赋值给一颗二叉树  2.具体代码  1.树的构建方法  ?...       *        * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已       *        * @param node       *            遍历的节点 ...       *        * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已       *        * @param node       *            遍历的节点 ...       *        * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已       *        * @param node       *            遍历的节点

    1.7K10

    二叉树的层序遍历(两种方法实现)

    大家好,又见面了,我是你们的朋友全栈君。 两种方法实现二叉树的层序遍历 1、说明 二叉树的层序遍历是面试经常会被考察的知识点,甚至要求当场写出实现过程。...层序遍历所要解决的问题很好理解,就是按二叉树从上到下,从左到右依次打印每个节点中存储的数据。...仔细看看层序遍历过程,其实就是从上到下,从左到右依次将每个数放入到队列中,然后按顺序依次打印就是想要的结果。...实现过程 1、首先将二叉树的根节点push到队列中,判断队列不为NULL,就输出队头的元素, 2、判断节点如果有孩子,就将孩子push到队列中, 3、遍历过的节点出队列, 4、循环以上操作...} } 数组实现: 实现过程 1、创建一个指针数组,保存二叉树结构体指针, 2、保存二叉树根节点,再申请变量 in、out ,控制数组,在遍历过程中,始终能找到节点和该节点的前一个节点

    85520

    Vue2剥丝抽茧-虚拟 dom 之更新

    oldCh = oldVnode.children const ch = vnode.children if (isUndef(vnode.text)) { // 如果没有 text 属性,递归遍历...== vnode.text) { nodeOps.setTextContent(elm, vnode.text) // 更新 text } } 上边就是更新的核心逻辑了,本质上就是对树的一个深度优先遍历...if 中判断它不是真实 dom 并且当前的 vnode 没有改变,然后就调用 pathVnode 方法来更新 dom 。...除此之外,创建 dom 的时候在 虚拟 dom 之绑定事件 我们调用了 cbs.create ,这里我们调用 cbs.update 来更新 dom 的属性。...总 这篇文章主要是加深对虚拟 dom 结构的了解,然后通过深度优先遍历对虚拟 dom 树进行遍历,因为我们假设了 dom 树的结构没有发生变化,所以遍历过程中直接进行节点的更新即可。

    34820

    大前端百科全书vue专题之虚拟dom+diff算法

    的真实dom元素之前 如果都没有命中,遍历oldStartIndex与oldEndIndex之间的元素,将它们的key与索引映射关系,放入一个Map中 如果Map中有newStartVnode的key,...while循环结束,newChildren 还没有遍历完,插入到 newEndVnode 之前 结束 用index做key 按理说,a,b,c三个li标签都是复用之前的,因为他们三个根本没改变,改变的只是前面新增了一个林三心...传统diff算法的算法复杂度为什么是o(n3) 对比节点O(n²) + 删除/添加节点O(n),合起来O(n³) 将两颗树中所有的节点一一对比需要O(n²)的复杂度 在对比过程中发现旧节点在新的树中未找到...,那么就需要把旧节点删除,删除一棵树的一个节点(找到一个合适的节点放到被删除的位置)的时间复杂度为O(n) 同理添加新节点的复杂度也是O(n),合起来diff两个树的复杂度就是O(n³) 时间复杂度...,data,children,text,elm} else if (typeof c === "object" && c.sel) { // 这个时候在 使用h()的时候 c = {sel,

    75500

    virtualdom diff算法实现分析

    当状态变更的时候,新生成一个对象,然后比较两棵树的差距 根据变更进行dom操作 virtual的本质就是在js和dom之间增加了一个缓存 vue的virtualdom实现使用了snabbdom,来看下算法的具体实现...] 深度优先遍历,比较差异 UI状态变更时,产生新的vnode,跟旧的vnode进行对比,在实际的代码中,会对新旧两棵树进行一个深度优先的遍历 [image] 在深度优先遍历的时候,每遍历到一个节点就把该节点和新的的树进行对比...vnode时候生成,如果满足相似,则进行patchnode说明在新的vnodes中复用了旧的vnodes中的节点,只是移位或者其他插入修改操作,如果没有相似,则从旧的vnode中查看是否有相同的key的...,vnode进行了左移,更新dom,parentElm.insertBefore(oldEndVnode.elm, oldStartVnode.elm); 若都没有命中,则从oldvnode中,查找跟newStartVnode.key...,比较差异 UI状态变更时,产生新的vnode,跟旧的vnode进行对比,在实际的代码中,会对新旧两棵树进行一个深度优先的遍历 [image] 在深度优先遍历的时候,每遍历到一个节点就把该节点和新的的树进行对比

    1.4K50

    Vue进阶 Diff算法详解

    虚拟DOM就是把真实DOM树的结构和信息抽象出来,以对象的形式模拟树形结构,如下: 真实DOM: Hello World 对应的虚拟DOM就是: let...渲染真实DOM会有一定的开销,如果每次修改数据都进行真实DOM渲染,都会引起DOM树的重绘和重排,性能开销很大。那么有没有可能只修改一小部分数据而不渲染整个DOM呢?...有个API叫 Vue.nextTick 二、 Diff算法 传统Diff算法 遍历两棵树中的每一个节点,每两个节点之间都要做一次比较。...newStartVnode = newCh[++newStartIdx] } else { // 如果没有相同的Key,执行createElm方法创建元素 if...子元素列表的Diff,进行头对头、尾对尾、头对尾等系列比较,直到遍历完两个元素的子元素列表。 或一个列表先遍历完了,直接addVnode / removeVnode。

    66330

    【数据结构】关于二叉树,你必须知道的遍历方法!!!

    2.非递归遍历 2.1引言 在遍历中,当我们打印一个结点的左树时,此时发现在左树打印完时,还需要通过结点的引用来遍历结点的右树,所以我们这里当结点还有用时,就要将结点存放在一个容器中,...2.遍历思路: 首先创建一个栈,若根结点不为空那么就放入栈中,此时然后遍历左树,在遍历过程中要进行每个结点的值域打印,并且放入栈中,然后当左树遍历时为空,那么就进行出栈,并且遍历出栈结点的右树...,就出栈 cur=top.right; //遍历出栈结点的右树 } } 注意:在跳出内循环时,要进行栈顶元素的右树遍历...遍历思路: 和前序遍历基本一致,但是由于中序遍历的思路是(左子树->根结点->右子树),所以只能在遍历左树后遇到空结点才能够进行打印,然后再遍历右树,若右树为空,则返回,并进行打印结点,在遍历此节点的右树...4.总结 小编在这期讲述了二叉树遍的两种方法,分别为递归与非递归遍历,两者各不相同,各有优点,递归方法,代码简单但是内部原理不易,而非递归方法,更容易想到。

    14910

    virtualdom diff算法实现分析

    - 当状态变更的时候,新生成一个对象,然后比较两棵树的差距 - 根据变更进行dom操作 virtual的本质就是在js和dom之间增加了一个缓存 vue的virtualdom实现使用了snabbdom...,比较差异 UI状态变更时,产生新的vnode,跟旧的vnode进行对比,在实际的代码中,会对新旧两棵树进行一个深度优先的遍历 !...,关键字为h函数初始化vnode时候生成,如果满足相似,则进行patchnode说明在新的vnodes中复用了旧的vnodes中的节点,只是移位或者其他插入修改操作,如果没有相似,则从旧的vnode中查看是否有相同的...,比较差异 UI状态变更时,产生新的vnode,跟旧的vnode进行对比,在实际的代码中,会对新旧两棵树进行一个深度优先的遍历 !...,每遍历到一个节点就把该节点和新的的树进行对比。

    1K60

    手写 Vue (一):虚拟 DOM

    我们知道在浏览器中,每一个DOM节点都是一棵“树”。作为树中一个节点,至少包含两个部分,即节点数据和子节点。...tag 为元素标签,data为属性数据,当节点是叶子节点,没有children,那么就用text表示节点显示的文本(事实上,文本在真实DOM中也是一个特殊的节点,它没有tag,因此为了处理方便,在虚拟节点中...和createVNode不同的是,createElm接受的vnode参数是一课树,因此,需要使用递归遍历整个VNode树,最后得到实际也是一个真实DOM节点树。...,实现$mount方法的基本功能也就简单了。...重新修改实例属性值(例如vm.text)并不能触发页面的重新渲染,也就是没有响应式; 只有完整创建一个新的DOM树的方法,对于已经创建好的DOM,重新更新,必须销毁整个DOM树,重新创建,即没有对新旧vnode

    78830
    领券