Morris本质就是线索二叉树,我们从leetcode中的一道easy题来看看如何使用Morris树求解



Morris 遍历算法是另一种遍历二叉树的方法,它能将非递归的中序遍历空间复杂度降为 O(1)。

Morris 遍历算法整体步骤如下(假设当前遍历到的节点为 x):

1.如果 x 无左孩子,先将 x 的值加入答案数组,再访问 x 的右孩子,即 x=x.right。

2.如果 x 有左孩子,则找到 x 左子树上最右的节点(即左子树中序遍历的最后一个节点,x 在中序遍历中的前驱节点),我们记为predecessor。根据 predecessor 的右孩子是否为空,进行如下操作。

(1)如果 predecessor 的右孩子为空,则将其右孩子指向 x,然后访问 x 的左孩子,即 x =x.left。

(2)如果 predecessor 的右孩子不为空,则此时其右孩子指向 x,说明我们已经遍历完 x 的左子树,我们将 predecessor 的右孩子置空,将 x 的值加入答案数组,然后访问 x 的右孩子,即 x = x.right。

3.重复上述操作,直至访问完整棵树。


以下为java代码

class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<Integer>();TreeNode predecessor = null;while (root != null) {if (root.left != null) {// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止predecessor = root.left;while (predecessor.right != null && predecessor.right != root) {predecessor = predecessor.right;}// 让 predecessor 的右指针指向 root,继续遍历左子树if (predecessor.right == null) {predecessor.right = root;root = root.left;}// 说明左子树已经访问完了,我们需要断开链接else {res.add(root.val);predecessor.right = null;root = root.right;}}// 如果没有左孩子,则直接访问右孩子else {res.add(root.val);root = root.right;}}return res;}
}

复杂度分析

时间复杂度:O(n),其中 n 为二叉搜索树的节点个数。Morris 遍历中每个节点会被访问两次,因此总时间复杂度为 O(2n)=O(n)。

空间复杂度:O(1)。


本文是从leetcode中摘抄一部分,对我个人的学习很有帮助,由于不是转载,就当作原创吧。

求赞

原题在这94. 二叉树的中序遍历 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

Morris 中序遍历相关推荐

  1. Leetcode501. Morris中序遍历

    文章概览 Morris中序遍历 Morris中序遍历算法详解 Leetcode 501题目描述 解题思路 完整代码 Morris中序遍历 一般二叉树的中序遍历需要用到递归算法,在递归过程中,程序会自动 ...

  2. [Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历]

    [问题描述][困难] [解答思路] 1. 显示中序遍历 时间复杂度:O(N) 空间复杂度:O(N) class Solution {public void recoverTree(TreeNode r ...

  3. 二叉树中序遍历的三种方法

    题目描述: 给定一个二叉树的根节点root,返回它的中序遍历. 方法一:递归 思路与算法: 二叉树的中序遍历:按照访问左子树-根节点-右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样 ...

  4. C++ morris inorder二叉树中序遍历(附完整源码)

    C++ morris inorder二叉树中序遍历 morris inorder二叉树中序遍历算法的完整源码(定义,实现,main函数测试) morris inorder二叉树中序遍历算法的完整源码( ...

  5. Morris遍历算法 树的中序遍历

    Morris遍历算法 树的中序遍历 树的中序遍历 一.普通方法 1.递归实现 2.栈实现 二.Morris遍历 1.算法 2.代码 总结 树的中序遍历 对于当前结点,先输出它的左孩子,然后输出该结点, ...

  6. 二叉树的Morris遍历:先序遍历和中序遍历

    二叉树的Morris遍历:先序遍历和中序遍历 提示:本节来说二叉树的Morris遍历,面试的高超优化技能! 此前学的关于二叉树的概念,先序遍历,中序遍历,后续遍历(这仨统称DFS遍历)和按层的方式遍历 ...

  7. leetcode94 二叉树的中序遍历

    给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3]    1     \      2     /    3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代 ...

  8. 二叉树:先序遍历,中序遍历,后序遍历,层序/层次遍历

    目录 二叉树 二叉树的递归遍历 先序递归遍历 中序递归遍历 后序递归遍历 二叉树的非递归遍历 先序遍历使用栈结构 中序遍历使用栈结构 后序遍历使用栈结构 中序遍历:(morris遍历)空间复杂度O(1 ...

  9. 2. 二叉树的中序遍历 (inOrder)

    头文件: 用到的是前序遍历中的头文件,具体可参见 "二叉树的前序遍历" 一,中序遍历的概念 中序遍历                 按照 左儿子-根节点-右儿子 的顺序访问二叉树 ...

  10. 非递归中序遍历二叉树总结(2种方法)

    算法 非递归中序遍历二叉树总结(2种方法) @author:Jingdai @date:2020.12.03 传送门 非递归先序遍历二叉树 非递归后序遍历二叉树 方法1 先序遍历是第一次遇到该节点遍历 ...

最新文章

  1. fox pro删除单条数据_删库之后不要着急跑路,教你神不知鬼不觉找回数据
  2. 24、Java并发性和多线程-信号量
  3. Android中的基础控件TextView、Button、ImageView、EditText、ProgressBar
  4. cf 1511 D. Min Cost String
  5. python中标识符的命名规则_Python——标识符的命名规则
  6. SQL语句的优化建议
  7. 搭建Vgg16训练CIFAR10数据集
  8. 装逼技能:怎样优雅地摆放桌面图标?
  9. 计算机端口 串口 并口是什么,那些年我们使用的电脑串行,并行接口,你们是否还记得?...
  10. java开发面试自我介绍模板_java面试自我介绍范文
  11. [Javascript 高级程序设计]学习心得记录11 js的BOM
  12. 集体过冬,Hyper-V为企业省钱
  13. 免费AWS EC2实例
  14. 疫情开发,软件测试行情趋势是怎么样的?
  15. MATH1013总结
  16. bios怎么设置USB启动
  17. Cognos入门教程
  18. 将 confirm的确定取消修改为是否
  19. 软件工程-耦合与内聚简单实例
  20. 期货投机原理(专业投机原理期货篇)

热门文章

  1. 操作手册与用户手册的区别
  2. Linux技术——lsof命令详解
  3. 关于搭建k8s集群遇到的问题与解决方法
  4. # 你也可以在你的微信 or QQ头像添加小国旗了,超简单!
  5. 肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
  6. 学电力好还是计算机好,毕业后想进电力系统上班?这三个专业可优先考虑
  7. BZOJ3557: [Ctsc2014]随机数
  8. 人生的智慧——叔本华
  9. arm跑操作系统的意义_上手一个具体而微的 ARM 操作系统
  10. S/HIC 系列软件:diploS/HIC 利用 CNN 和非定向基因型数据识别 软/硬 清扫