图解二叉树的Morris(莫里斯)遍历

二叉树的Morris(莫里斯)遍历

本文参考链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/490846864/

文章目录

    • 二叉树的Morris(莫里斯)遍历
      • 模板代码
      • 前序遍历
      • 中序遍历
      • 后序遍历

Morris 遍历使用二叉树节点中大量指向 null 的指针,时间复杂度:O(n),额外空间复杂度:O(1)。

Morris 的整体思路就是将 以某个根结点开始,找到它左子树的最右侧节点之后与这个根结点进行连接。

在这里插入图片描述

我们可以从图中看到,连接之后,指针是可以完整的从根节点顺着下一个节点遍历,将整棵树遍历完毕,直到 7 这个节点右侧没有指向。

模板代码

首先介绍morris的模板代码,带*的注释表示该行为指定遍历所要增加的内容,可以先不管。

模板代码的流程图如下所示:

在这里插入图片描述

在这里插入图片描述

public List<Integer> traversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}//1.定义cur和prevTreeNode cur = root;TreeNode prev = null;//2.当cur不为空时while (cur != null) {//2.1prev为cur左子树prev = cur.left;//2.2prev不为空时if (prev != null) {//2.2.1用prev找到左子树最右侧节点while (prev.right != null && prev.right != cur) {prev = prev.right;}//2.2.2prev右子树不为空时,连接if (prev.right == null) {prev.right = cur;//*前+res.add(cur.val);cur = cur.left;} else { //2.2.3prev右子树不为空时,断开连接prev.right = null;//*中+res.add(cur.val); *后+print(cur.left)cur = cur.right;}} else { //2.3prev为空时//*前中+res.add(cur.val);cur = cur.right;}}//*后+print(root)return res;
}

前序遍历

public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}//1.定义cur和prevTreeNode cur = root;TreeNode prev = null;//2.当cur不为空时while (cur != null) {//2.1prev为cur左子树prev = cur.left;//2.2prev不为空时if (prev != null) {//2.2.1用prev找到左子树最右侧节点while (prev.right != null && prev.right != cur) {prev = prev.right;}//2.2.2prev右子树不为空时,连接if (prev.right == null) {prev.right = cur;res.add(cur.val);cur = cur.left;} else { //2.2.3prev右子树不为空时,断开连接prev.right = null;cur = cur.right;}} else { //2.3prev为空时res.add(cur.val);cur = cur.right;}}return res;
}

中序遍历

public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}//1.定义cur和prevTreeNode cur = root;TreeNode prev = null;//2.当cur不为空时while (cur != null) {//2.1prev为cur左子树prev = cur.left;//2.2prev不为空时if (prev != null) {//2.2.1用prev找到左子树最右侧节点while (prev.right != null && prev.right != cur) {prev = prev.right;}//2.2.2prev右子树不为空时,连接if (prev.right == null) {prev.right = cur;cur = cur.left;} else { //2.2.3prev右子树不为空时,断开连接prev.right = null;res.add(cur.val);cur = cur.right;}} else { //2.3prev为空时res.add(cur.val);cur = cur.right;}}return res;
}

后序遍历

当连接已完成时,断开连接后,打印下层的单链表,比如返回到2时,打印4,返回到1时,打印5,2,涉及到了逆序打印单链表的内容。注意应该是打印下一层,而不是当前层。循环结束后打印根节点所在的一侧,即7,3,1。

在这里插入图片描述

List<Integer> res = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {if (root == null) {return res;}//1.定义cur和prevTreeNode cur = root;TreeNode prev = null;//2.当cur不为空时while (cur != null) {//2.1prev为cur左子树prev = cur.left;//2.2prev不为空时if (prev != null) {//2.2.1用prev找到左子树最右侧节点while (prev.right != null && prev.right != cur) {prev = prev.right;}//2.2.2prev右子树不为空时,连接if (prev.right == null) {prev.right = cur;cur = cur.left;} else { //2.2.3prev右子树不为空时,断开连接prev.right = null;print(cur.left); //打印左子树cur = cur.right;}} else { //2.3prev为空时cur = cur.right;}}print(root); //打印根节点所在一侧return res;
}//打印链表
public void print(TreeNode head) {TreeNode revList = reverseList(head);TreeNode cur = revList;while (cur != null) {res.add(cur.val);cur = cur.right;}reverseList(revList);
}//翻转单链表
public TreeNode reverseList(TreeNode head) {TreeNode cur = head;TreeNode prev = null;while (cur != null) {TreeNode next = cur.right;cur.right = prev;prev = cur;cur = next;}return prev;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaweb数据库操作

本文主要内容有C3P0数据库连接池&#xff0c;dbutils的使用&#xff0c;元数据的应用 在对数据库进行增删改查时&#xff0c;使用数据库连接池可以有效的提高效率&#xff0c;节省资源&#xff0c;C3P0是Apache组织提供的一个有效方式 C3P0的XML配置文件&#xff0c;文件名必…

PHP5.5中新增的参数跳跃和生成器功能介绍

生成器 目前&#xff0c;自定义迭代器很少使用&#xff0c;因为它们的实现&#xff0c;需要大量的样板代码。生成器解决这个问题&#xff0c;并提供了一种简单的样板代码来创建迭代器。 例如&#xff0c;你可以定义一个范围函数作为迭代器: <?phpfunction *xrange($sta…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 11丨产品销售分析 III【难度中等】

活动介绍&#xff1a; 「数据仓库技术交流群」已经正式启动每日SQL打卡&#xff0c;帮助大家扎实基础&#xff0c;努力工作之余&#xff0c;别忘了自我提升。另有超多CSDN 周边礼物相送。 欢迎报名和邀请小伙伴参与&#xff0c;一个人可能走得很快&#xff0c;但一群人会走得很…

瓜分340亿美元物联网芯片半导体市场!机会在这五大行业【附下载】| 智东西内参...

来源&#xff1a;智东西摘要&#xff1a;市场压力之下&#xff0c;物联网为工业、汽车、智慧城市、医疗健康和消费半导体提供了新的解决方案。半导体产业渗透了我们生活中的各个方面&#xff0c;从闹钟、微波炉到手机、笔记本。而现在&#xff0c;物联网技术正在为全球半导体市…

Android之数据库操作

安卓数据库帮助类 /*** 数据库帮助类&#xff0c;用于管理数据库* author Administrator**/ public class PersonSQLiteOpenHelper extends SQLiteOpenHelper {private String tag"PersonSQLiteOpenHelper";public PersonSQLiteOpenHelper(Context context) {//数据…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 11丨产品销售分析 II【难度简单】

活动介绍&#xff1a; 「数据仓库技术交流群」已经正式启动每日SQL打卡&#xff0c;帮助大家扎实基础&#xff0c;努力工作之余&#xff0c;别忘了自我提升。 欢迎报名和邀请小伙伴参与&#xff0c;一个人可能走得很快&#xff0c;但一群人会走得很远。 &#x1f345;题目汇总(…

用互联网大脑模型分析滴滴的战略意图和战术失误

作者&#xff1a;刘锋 互联网进化论作者&#xff0c;计算机博士滴滴出行与美国的Uber&#xff0c;本质上都是基于互联网的智能打车软件&#xff0c;让任何拥有家用汽车的司机都可以与出租车司机一样&#xff0c;服务于打车用户。 在滴滴&#xff0c;Uber出世之前的出租车行业…

Android数据存储之sharedpreferences与Content Provider

android中对数据操作包含有&#xff1a; file, sqlite3, Preferences, ContectResolver与ContentProvider前三种数据操作方式都只是针对本应用内数据&#xff0c;程序不能通过这三种方法去操作别的应用内的数据 其中sqlite3已经在上一节中讲述了&#xff0c;本节主要包含shar…

vtk类之vtkImageReslice:基本算法,对体数据沿着轴进行切片

沿着轴方向切割体数据。 vtkImageReslice 是几何图形过滤器中的瑞士军刀。他可以排列&#xff0c;旋转&#xff0c;翻转&#xff0c;缩放&#xff0c;重新采样&#xff0c;变形, 还有随意再任何效率与图像质量组合下&#xff0c;渲染图像。简单的操作&#xff0c;像排列&#x…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 12丨游戏玩法分析 V【难度困难】

活动介绍&#xff1a; 「数据仓库技术交流群」已经正式启动每日SQL打卡&#xff0c;帮助大家扎实基础&#xff0c;努力工作之余&#xff0c;别忘了自我提升。另有超多CSDN 周边礼物相送。 欢迎报名和邀请小伙伴参与&#xff0c;一个人可能走得很快&#xff0c;但一群人会走得很…

仅需1/5成本:TPU是如何超越GPU,成为深度学习首选处理器的

作者&#xff1a;Kaz Sato 来源&#xff1a;Google Cloud、机器之心摘要&#xff1a;张量处理单元&#xff08;TPU&#xff09;是一种定制化的 ASIC 芯片&#xff0c;它由谷歌从头设计&#xff0c;并专门用于机器学习工作负载。TPU 为谷歌的主要产品提供了计算支持&#xff0c;…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 12丨销售分析 III【难度简单】

活动介绍&#xff1a; 「数据仓库技术交流群」已经正式启动每日SQL打卡&#xff0c;帮助大家扎实基础&#xff0c;努力工作之余&#xff0c;别忘了自我提升。另有超多CSDN 周边礼物相送。 欢迎报名和邀请小伙伴参与&#xff0c;一个人可能走得很快&#xff0c;但一群人会走得很…

[唐胡璐]Excel技巧 - 使用Excel 2007完成多人协同录入工作

下面我们来介绍下Excel 2007的共享功能。 一、设置共享 启动Excel 2007&#xff0c;打开需要设置共享的工作薄文档&#xff0c;切换到“审阅”菜单选项卡中&#xff0c;单击“更改”组中的“共享工作薄”按钮&#xff0c;打开“共享工作薄”对话框&#xff0c;如下图所示。 …

Android之jni入门

jni即java native interface&#xff0c;使用jni我们可以在JAVA中调用C代码&#xff0c;提高了效率&#xff0c;可以复用代码&#xff0c;可以灵活的应用于各种场景 怎么使用JNI 安装软件 1.NDK 用于将C代码编译成so库 2.CygWin 在windows下模拟linux环境 3.CDT 在eclipse…

腾讯投资过 600 多家公司不惊奇,京东也有出手 260+ | 大公司投资并购盘点

来源&#xff1a;IT桔子A 股一片绿&#xff0c;这已经不是满屏绿色的第一天了&#xff0c;2018 年以来&#xff0c;A 股经历了起起落落落落落落……尤其在中美贸易战不断升级后&#xff0c;A 股的代表颜色就成了绿色&#xff0c;少数会有几家企业翻红&#xff0c;然而过不了几天…

埋点技术:“呵呵,你在网上的一举一动,都在我眼皮子底下”

&#x1f345; 作者主页&#xff1a;不吃西红柿 &#x1f345; 简介&#xff1a;CSDN博客专家 & 总榜前十&#x1f3c6;、HDZ核心组成员。欢迎点赞、收藏、评论 &#x1f345; 粉丝专属福利&#xff1a;知识体系、面试题库、技术互助、简历模板。文末公众号领取 1、什么是…

printf的格式控制的完整格式

printf的格式控制的完整格式 printf的格式控制的完整格式&#xff1a;% - 0 m.n l或h 格式字符下面对组成格式说明的各项加以说明&#xff1a;①%&#xff1a;表示格式说明的起始符号&#xff0c;不可缺少。②-&#xff1a;有-表示左对齐输出&#xff0c;如省略表示右对…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 13丨每日新用户统计【难度中等】

活动介绍&#xff1a; 「数据仓库技术交流群」已经正式启动每日SQL打卡&#xff0c;帮助大家扎实基础&#xff0c;努力工作之余&#xff0c;别忘了自我提升。另有超多CSDN 周边礼物相送。 欢迎报名和邀请小伙伴参与&#xff0c;一个人可能走得很快&#xff0c;但一群人会走得很…

美国斯坦福大学发布2025计划, 创立开环大学, 彻底颠覆全球高等教育

来源&#xff1a;钱塘号《斯坦福大学2025计划》在以设计思考理论著称的斯坦福大学设计学院牵头下正式启动&#xff0c;这次教育改革改变了以往自上而下的方式&#xff0c;代之以师生为主导。与其说《斯坦福大学2025计划》是一个方案&#xff0c;不如说它是一个对未来大学模式进…

Android之jni深入

小技巧&#xff1a;自动生成 java本地方法对应的c代码的方法名 javah 指令 全类名 java1.6版本 class C:\workspace\HelloWorldFromC2\bin\classes java1.7以上 src C:\workspace\HelloWorldFromC2\src 获得方法的签名的方法 javap -s 打印方法的签名 注意要cd到 C:\workspa…