• 数据结构--Morris遍历--二叉树的遍历


    二叉树——二叉树的遍历(递归与迭代)

    Morris遍历

    利用Morris遍历实现二叉树的先序, 中序, 后续遍历, 时间复杂度O(N), 额外空间复杂度O(1)。

    如果一个结点有左孩子,则回到该结点两次,否则只回到一次,而且当第二次回到该结点时,左子树已经遍历完了

    Morris遍历规则:

    1.来到的当前结点即为cur,如果cur没有左孩子,则cur向右移动,即cur = cur.right

    2.如果cur有左孩子,则找到cur左子树上最右的结点,记为mostRight

      ①如果mostRight的右指针指向null(第一次遍历到cur时),则将其指向当前结点cur,cur向左移动  cur = cur.left

      ②如果mostRight的右指针指向cur(第二次回到cur时),则让其指向null,cur向右移动  cur = cur.right

    package binaryTree.traverse;
    
    /**
     * Created by Skye on 2018/5/3.
     *
     * 当前结点cur
     * 1.如果cur没有左孩子,则cur = cur.right
     * 2.如果cur有左孩子,则找到cur左孩子的最右结点mostRight
     *   1)如果mostRight.right == null 则让mostRight.right = cur,cur = cur.left
     *   2)如果mostRight.right == cur,则让mostRight.right = null,cur= cur.right
     */
    public class MorrisTraversal {
    
        public static void morris(Tree node){
            if(node == null) return;
            Tree cur = node;
            while(cur != null){
                Tree mostRight = cur.left;
                if(mostRight != null){
                    while(mostRight.right != null && mostRight != cur){
                        mostRight = mostRight.right;
                    }
                    if(mostRight.right == null){
                        mostRight.right = cur;
                        cur = cur.left;
                        continue;
                    }else{
                        mostRight.right = null;
                    }
                }
                cur = cur.right;
            }
        }
    
        public static void morrisIn(Tree node){
            if(node == null) return;
            Tree cur = node;
            while(cur != null){
                Tree mostRight = cur.left;
                if(mostRight != null){
                    while(mostRight.right != null && mostRight.right != cur){
                        mostRight = mostRight.right;
                    }
                    if(mostRight.right == null){
                        mostRight.right = cur;
                        cur = cur.left;
                        continue;
                    }else{
                        mostRight.right = null;
                    }
                }
                System.out.print(cur.val + " ");
                cur = cur.right;
            }
        }
    
        public static void morrisPre(Tree tree){
            if(tree == null) return;
            Tree cur = tree;
            while(cur != null){
                Tree mostRight = cur.left;
                if(mostRight != null){
                    while(mostRight.right != null && mostRight.right != cur){
                        mostRight = mostRight.right;
                    }
                    if(mostRight.right == null){
                        mostRight.right = cur;
                        System.out.print(cur.val + " ");
                        cur = cur.left;
                        continue;
                    }else{
                        mostRight.right = null;
                    }
                } else{
                    System.out.print(cur.val + " ");
                }
    
                cur = cur.right;
            }
        }
    
        public static void morrisPost(Tree node){
            if(node == null) return;
            Tree cur = node;
            while(cur != null){
                Tree mostRight = cur.left;
                if(mostRight != null){
                    while(mostRight.right != null && mostRight.right != cur){
                        mostRight = mostRight.right;
                    }
                    if(mostRight.right == null){
                        mostRight.right = cur;
                        cur = cur.left;
                        continue;
                    }else{
                        mostRight.right = null;
                        printEdge(cur.left);
                    }
                }
                cur = cur.right;
            }
            printEdge(node);
        }
    
        public static void printEdge(Tree cur) {
            if(cur == null) return;
    
            int val = cur.val;
            printEdge(cur.right);
            System.out.print(val + " ");
        }
    
    }
    

      

    注:最后的反向输出一排右子树的方法:

    1.采用链表逆向输出

    public static void printEdge(Tree cur) {
            if(cur == null) return;
    
            int val = cur.val;
            printEdge(cur.right);
            System.out.print(val + " ");
        }
    

      

    2.先将链表反转,然后输出,最后在反转回来。

    public static void printEdge1(Tree cur){
            Tree tail = reverse(cur);
            Tree node = tail;
            while(node != null){
                System.out.print(node.val + " ");
                node = node.right;
            }
    
            reverse(tail);
        }
    
        public static Tree reverse(Tree node){
            Tree pre = null;
    
            while(node != null){
                Tree next = node.right;
                node.right = pre;
                pre = node;
                node = next;
            }
            return pre;
        }
    

      

  • 相关阅读:
    JavaScript总结(一)
    序列化函数
    random与os,sys模块
    认识模块
    时间模块
    日志处理
    异常处理
    类的约束
    反射
    区分函数以及方法
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/8988022.html
Copyright © 2020-2023  润新知