ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Morris遍历二叉树

2021-07-18 11:35:21  阅读:182  来源: 互联网

标签:遍历 TreeNode cur mostRight Morris right 二叉树 null


所谓Morris遍历,就是建立线索二叉树,然后在遍历的同时边建边拆。

主要思路就是,我先拿到当前节点,然后设置一个mostRight指向当前节点的左子树,然后不断地找右子树(这样做是为了找到当前节点的直接前驱节点)。找到之后,如果这个节点的右孩子指向为空,则指向当前节点,这就是建立线索二叉树;同时,为了不破坏二叉树的结构,当这个节点右孩子指向为当前节点时,我们就要把线索断掉,这就是拆。

左子树遍历完后,我们就需要遍历右子树。

具体可以看看视频教程:

Morris遍历

我们直接来看代码:

  1 package com.hw.list0710;
  2 
  3 public class Morris {
  4     static class TreeNode{
  5         TreeNode left;
  6         TreeNode right;
  7         int val;
  8         public TreeNode(int val, TreeNode left, TreeNode right){
  9             this.val = val;
 10             this.left = left;
 11             this.right = right;
 12         }
 13     }
 14 
 15     /**
 16      * 先序遍历线索二叉树
 17      * @param cur
 18      */
 19     private static void morrisPre(TreeNode cur){
 20         if(cur == null){
 21             return;
 22         }
 23         TreeNode mostRight = null;
 24         while(cur != null)
 25         {
 26             mostRight = cur.left;
 27             if(mostRight != null){
 28                 while(mostRight.right != null && mostRight.right != cur)
 29                 {
 30                     mostRight = mostRight.right;
 31                 }
 32                 if(mostRight.right == null){  //建立线索指针
 33                     mostRight.right = cur;
 34                     System.out.print(cur.val+" ");
 35                     cur = cur.left;
 36                     continue;
 37                 }else{
 38                     mostRight.right = null;  //删除线索指针
 39                 }
 40             }else{
 41                 System.out.print(cur.val+" ");
 42             }
 43             cur = cur.right;  //左边没了,要到右边;左边遍历完了,也要到右边
 44         }
 45     }
 46 
 47     /**
 48      * 中序遍历线索二叉树
 49      * @param cur
 50      */
 51     private static void morrisMid(TreeNode cur){
 52         if(cur == null){
 53             return;
 54         }
 55         TreeNode mostRight = null;
 56         while(cur != null)
 57         {
 58             mostRight = cur.left;
 59             if(mostRight != null){
 60                 while(mostRight.right != null && mostRight.right != cur)
 61                 {
 62                     mostRight = mostRight.right;
 63                 }
 64                 if(mostRight.right == null){
 65                     mostRight.right = cur;
 66                     cur = cur.left;
 67                     continue;
 68                 }else{
 69                     System.out.print(cur.val+" ");
 70                     mostRight.right = null;
 71                 }
 72             }else{
 73                 System.out.print(cur.val+" ");
 74             }
 75             cur = cur.right;
 76         }
 77     }
 78 
 79     /**
 80      * 反转链表
 81      * @param head
 82      * @return
 83      */
 84     private static TreeNode reverse(TreeNode head){
 85         TreeNode pre = null;
 86         TreeNode cur, next;
 87         cur = head;
 88         while(cur != null)
 89         {
 90             next = cur.right;
 91             cur.right = pre;
 92             pre = cur;  //指向当前节点的上一个节点的指针前移
 93             cur = next;
 94         }
 95         return pre;
 96     }
 97 
 98     /**
 99      * 打印链表节点
100      * @param head
101      */
102     private static void printNode(TreeNode head){
103         TreeNode tail = reverse(head);
104         while(tail != null)
105         {
106             System.out.print(tail.val+" ");
107             tail = tail.right;
108         }
109         reverse(tail);
110     }
111 
112     /**
113      * 后序遍历线索二叉树
114      * @param cur
115      */
116     private static void morrisLast(TreeNode cur){
117         if(cur == null){
118             return;
119         }
120         TreeNode root = cur;
121         TreeNode mostRight = null;
122         while(cur != null)
123         {
124             mostRight = cur.left;
125             if(mostRight != null){
126                 while(mostRight.right != null && mostRight.right != cur)
127                 {
128                     mostRight = mostRight.right;
129                 }
130                 if(mostRight.right == null){  
131                     mostRight.right = cur;
132                     cur = cur.left;
133                     continue;
134                 }else{
135                     mostRight.right = null;  
136                     printNode(cur.left);
137                 }
138             }
139             cur = cur.right;  
140         }
141         printNode(root);
142     }
143 
144     public static void main(String[] args) {
145         TreeNode node6 = new TreeNode(6, null, null);
146         TreeNode node7 = new TreeNode(7, null, null);
147         TreeNode node5 = new TreeNode(5, node6, node7);
148         TreeNode node4 = new TreeNode(4, null, null);
149         TreeNode node2 = new TreeNode(2, node4, node5);
150         TreeNode node3 = new TreeNode(3, null, null);
151         TreeNode node1 = new TreeNode(1, node2, node3);
152         System.out.print("先序遍历:");
153         morrisPre(node1);
154         System.out.println();
155         System.out.print("中序遍历:");
156         morrisMid(node1);
157         System.out.println();
158         System.out.print("后序遍历:");
159         morrisLast(node1);
160     }
161 }

 

标签:遍历,TreeNode,cur,mostRight,Morris,right,二叉树,null
来源: https://www.cnblogs.com/EvanTheGreat/p/15026080.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有