文章目录

  • 二叉树遍历-线索二叉树(Morris)
    • 1、前序遍历-线索二叉树
    • 2、中序遍历-线索二叉树(常用)
    • 3、后序遍历-线索二叉树(不推荐)
    • 实验源码:

二叉树遍历-线索二叉树(Morris)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=31

1、前序遍历-线索二叉树

https://www.bilibili.com/video/BV1Jv411A7Ty?p=32

 //1、前序-线索二叉树:根   左  右public static void morrisPre(TreeNode cur){if(cur==null){return;}TreeNode mosRight=null;while(cur!=null){mosRight=cur.left;if(mosRight!=null){while (mosRight.right!=null&&mosRight.right!=cur){mosRight=mosRight.right;}if(mosRight.right==null){//1、重点:建立线索指针mosRight.right=cur;System.out.println(cur.val);cur=cur.left; //指针左移,并继续找前区节点continue;}else{//2、重点:mosRight.right=cur; 删除线索指针mosRight.right=null;}}else{System.out.println(cur.val);}cur=cur.right;}}

2、中序遍历-线索二叉树(常用)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=32

中序遍历是比较容易也是常用的方法,从左向右看,其实中序遍历就是一个二叉树的投影。
左子树最右侧的节点就是右侧节点的前驱节点,比如找 1 的前驱节点就是 7 。

    //2、中序-线索二叉树:左  根  右public static void morrisMid(TreeNode cur){if(cur==null){return;}TreeNode mosRight=null;while(cur!=null){mosRight=cur.left;if(mosRight!=null){while (mosRight.right!=null&&mosRight.right!=cur){mosRight=mosRight.right;}if(mosRight.right==null){//1、重点:建立线索指针mosRight.right=cur;cur=cur.left; //指针左移,并继续找前区节点continue;}else{//2、重点:mosRight.right=cur; 删除线索指针mosRight.right=null;}}else{}System.out.println(cur.val);cur=cur.right;}}

3、后序遍历-线索二叉树(不推荐)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=33

 //3、后序-线索二叉树:左   右  根// Morris后续遍历:只关注有左子树的节点,第二次遍历到的时候逆序打印左子树的右边界,最后再单独打印整棵树的右边界public static void morrisPost(TreeNode root){if(root == null){return;}TreeNode current = root;TreeNode mostRight = null;while(current != null){mostRight = current.left;// current 有左子树时,就要进行Morris遍历if(mostRight != null){while(mostRight.right != null && mostRight.right != current){// 找到左子树的最右子节点mostRightmostRight = mostRight.right;}// mosrRight找到了,说明是第一次来到curif(mostRight.right == null){mostRight.right = current;current = current.left;continue;}else{mostRight.right = null;// 第二次到达该节点,就逆序打印其左子树的右边界printEdge(current.left);}}// 无左子树 或者左子树已经遍历完了就遍历右子树current = current.right;}// 打印整棵树的右边界printEdge(root);}// 逆序打印node节点的右边界,单链表反转的形式实现逆序public static void printEdge(TreeNode node){TreeNode tail = reverseEdge(node);TreeNode current = tail;  // 记录下,用于后面的反转while(current != null){System.out.print(current.val + " ");current = current.right;}// 打印完成,还需要将树还原,再反转一次reverseEdge(tail);}public static TreeNode reverseEdge(TreeNode node){TreeNode pre = null;TreeNode next = null;while(node != null){next = node.right;node.right = pre;pre = node;node = next;}return pre;}

实验源码:

package com.example.rabbitmq;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;@SpringBootTest
/*二叉树遍历-Morris线索二叉树*/
class SuanfaApplicationTests19 {//定义一个二叉树static class TreeNode{public int val;public TreeNode left;public TreeNode right;public int deep;//深度public TreeNode(){}public TreeNode(int val){this.val=val;}public TreeNode(int val,TreeNode left,TreeNode right){this.val=val;this.left=left;this.right=right;}}//1、前序-线索二叉树:根   左  右public static void morrisPre(TreeNode cur){if(cur==null){return;}TreeNode mosRight=null;while(cur!=null){mosRight=cur.left;if(mosRight!=null){while (mosRight.right!=null&&mosRight.right!=cur){mosRight=mosRight.right;}if(mosRight.right==null){//1、重点:建立线索指针mosRight.right=cur;System.out.println(cur.val);cur=cur.left; //指针左移,并继续找前区节点continue;}else{//2、重点:mosRight.right=cur; 删除线索指针mosRight.right=null;}}else{System.out.println(cur.val);}cur=cur.right;}}//2、中序-线索二叉树:左  根  右public static void morrisMid(TreeNode cur){if(cur==null){return;}TreeNode mosRight=null;while(cur!=null){mosRight=cur.left;if(mosRight!=null){while (mosRight.right!=null&&mosRight.right!=cur){mosRight=mosRight.right;}if(mosRight.right==null){//1、重点:建立线索指针mosRight.right=cur;cur=cur.left; //指针左移,并继续找前区节点continue;}else{//2、重点:mosRight.right=cur; 删除线索指针mosRight.right=null;}}else{}System.out.println(cur.val);cur=cur.right;}}//3、后序-线索二叉树:左   右  根// Morris后续遍历:只关注有左子树的节点,第二次遍历到的时候逆序打印左子树的右边界,最后再单独打印整棵树的右边界public static void morrisPost(TreeNode root){if(root == null){return;}TreeNode current = root;TreeNode mostRight = null;while(current != null){mostRight = current.left;// current 有左子树时,就要进行Morris遍历if(mostRight != null){while(mostRight.right != null && mostRight.right != current){// 找到左子树的最右子节点mostRightmostRight = mostRight.right;}// mosrRight找到了,说明是第一次来到curif(mostRight.right == null){mostRight.right = current;current = current.left;continue;}else{mostRight.right = null;// 第二次到达该节点,就逆序打印其左子树的右边界printEdge(current.left);}}// 无左子树 或者左子树已经遍历完了就遍历右子树current = current.right;}// 打印整棵树的右边界printEdge(root);}// 逆序打印node节点的右边界,单链表反转的形式实现逆序public static void printEdge(TreeNode node){TreeNode tail = reverseEdge(node);TreeNode current = tail;  // 记录下,用于后面的反转while(current != null){System.out.print(current.val + " ");current = current.right;}// 打印完成,还需要将树还原,再反转一次reverseEdge(tail);}public static TreeNode reverseEdge(TreeNode node){TreeNode pre = null;TreeNode next = null;while(node != null){next = node.right;node.right = pre;pre = node;node = next;}return pre;}@Testpublic void sf0(){//构造一个二叉树TreeNode node7=new TreeNode(7,null,null);TreeNode node6=new TreeNode(6,null,null);TreeNode node5=new TreeNode(5,node6,node7);TreeNode node4=new TreeNode(4,null,null);TreeNode node3=new TreeNode(3,null,null);TreeNode node2=new TreeNode(2,node4,node5);TreeNode node1=new TreeNode(1,node2,node3);System.out.println("-------前序遍历-线索二叉树------");morrisPre(node1);System.out.println("-------中序遍历-线索二叉树------");morrisMid(node1);System.out.println("-------后序遍历-线索二叉树------");morrisPost(node1);}}

结果:

-------前序遍历-线索二叉树------
1
2
4
5
6
7
3
-------中序遍历-线索二叉树------
4
2
6
5
7
1
3
-------后序遍历-线索二叉树------
4
6
7
5
2
3
1

Java常见算法(五)【二叉树:morris遍历】相关推荐

  1. 【数据结构Note5】- 树和二叉树(知识点超细大全-涵盖常见算法 排序二叉树 线索二叉树 平衡二叉树 哈夫曼树)

    文章目录 5.1 树和二叉树引入 5.1.1 树的概念 5.1.2 树的表示 5.1.3 树中基本术语 5.2 二叉树 5.2.1 概念 5.2.2 二叉树的性质 5.2.3 特殊的二叉树 5.2.4 ...

  2. 深度优先遍历算法-03二叉树路径遍历问题

    二叉树路径遍历 简述 比较基础的一个DFS的题目,但是确实很多难题的模板.LeetCode很多二叉树的题本质上就是这个路径遍历. 本题为了输出路径,使用DFS的经典结构栈完成. 问题描述 给定一个二叉 ...

  3. 二叉树层次遍历算法 python_二叉树的遍历详解:前、中、后、层次遍历(Python实现)...

    二叉树的遍历详解:前.中.后.层次遍历(Python实现) 二叉树是一种常见的数据结构,而它的常见遍历方法有前序遍历.中序遍历.后续遍历.层次遍历--掌握这几种遍历方法是很有必要的. 假设我们二叉树节 ...

  4. lc501.二叉搜索树中的众数【线索二叉树Morris遍历->lc538】

    开始想的按普通二叉树一样,把值和计数放在一个数组里面,但是想想它是二叉搜索树,有什么特别的呢? 官方题解https://leetcode-cn.com/problems/find-mode-in-bi ...

  5. 算法(2)-二叉树的遍历(递归/迭代)python实现

    二叉树的遍历 1.深度优先DFS 1.1 DFS 递归解法 1.1.1先序遍历 1.1.2中序遍历 1.1.3后序遍历 1.2 DFS迭代解法 1.2.1先序遍历 1.2.2中序遍历 1.2.3后序遍 ...

  6. 数据结构与算法之二叉树广度遍历、深度遍历总结

    什么是树,它是和链表一样都是一种抽象数据类型(ADT),包括数据结构和对数据的操作. 树是一种二维平面的数据结构结构,它也是由节点组成的,只是它的后继节点不止一个,而链表的后继节点只有一个. 树具有以 ...

  7. JAVA常见算法题(二十五)

    /*** Java实现中文数字转换为阿拉伯数字* * * @author WQ**/ public class Demo26 {public static void main(String[] arg ...

  8. [Leetcode][第100题][JAVA][相同的树][二叉树][深度遍历][递归]

    [问题描述][中等] [解答思路] 深度遍历/递归 终止条件与返回值: 当两棵树的当前节点都为 null 时返回 true 当其中一个为 null 另一个不为 null 时返回 false 当两个都不 ...

  9. JAVA常见算法题(三十一)---冒泡排序

    package com.jege.spring.boot.hello.world;/*** java算法之冒泡排序<br>* 将数组按照从大到小的顺序排列<br>* * * @ ...

最新文章

  1. 创建一个显示所有预定义WPF颜色的ListBox
  2. PHP将数组存入数据库中的四种方式
  3. eclipse mat 分析dump文件,打开文件报错,out of memeory
  4. SQLServer 数据库主体在该数据库中拥有 架构,无法删除解决方法
  5. 淘宝开源的代码质量检测工具,太强大了!!
  6. 数据结构 KMP 算法实现
  7. 第二章 七个习惯概论
  8. linux配置超时_自动退出登录TMOUT
  9. 微信网络营销 你造吗?
  10. 软件测试选哪个技术方向分支_硬件测试转软件测试,应该选哪个方向
  11. overleaf 只能用jpg格式?visio生成jpg文件太大怎么办?
  12. <数据结构>倒拔二叉树
  13. MeSH 医学主题词数据库
  14. 在 CloudIDE 里实现天猫精灵自定义技能的业务逻辑
  15. 将访问控制更改为:共享级访问控制,并重启计算机使设置生效.,Internet应用模拟题...
  16. 二维数组根据每个数组的元素排序(奥运奖牌排序)的几种方法
  17. 西门子 Smart200 固件更新
  18. Soft-ICE使用说明及实例——破解ACDSee
  19. MySQL 到 MongoDB 实时数据同步实操分享
  20. 基于UCD9248的7系列FPGA电源控制系统实验笔记

热门文章

  1. SQL WHERE AND OR
  2. Parsing error: Cannot read file ‘c:\users\xxx\desktop\demo\tsconfig.json‘
  3. html封面设计图片手绘大全,一套富有创意的简约手绘插图,用于墙面装饰、明信片或小册子封面设计。手绘矢量设计元素。病媒EPS10....
  4. 「镁客早报」英特尔与紫光展锐分道扬镳;小米组织架构大调整...
  5. 破解基础----背的滚瓜烂熟差不多就会破解
  6. Python 实现子域名查询与爆破
  7. c语言编程正棱台体积,正交试验设计方案书与C语言实现.doc
  8. BUC算法及其Python实现
  9. Hbase统计表的行数的3种方法
  10. MATLAB显示剪切板不可用,电脑剪切板不能正常启动或者使用。