zoukankan      html  css  js  c++  java
  • Morris遍历


    /**
    * Morris遍历:可以将非递归遍历中的空间复杂度降为O(1)。从而实现时间复杂度为O(N),而空间复杂度为O(1)的精妙算法
    * <p>
    * 记作当前节点为cur。
    * 如果cur无左孩子,cur向右移动(cur=cur.right)
    * 如果cur有左孩子,找到cur左子树上最右的节点,记为mostright
    * 如果mostright的right指针指向空,让其指向cur,cur向左移动(cur=cur.left)
    * 如果mostright的right指针指向cur,让其指向空,cur向右移动(cur=cur.right)
    * <p>
    * 实现以上的原则,即实现了morris遍历。
    * <p>
    * 实质:建立一种机制,对于没有左子树的节点只到达一次,对于有左子树的节点会到达两次
    */
    public class Morris {

    public static void morris(Node head) {
    Node cur = head;
    Node mostRight;
    while (cur != null) {
    System.out.println(cur.value);
    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;
    }
    }
    cur = cur.right;
    }
    }

    public static void morrisIn(Node head) {
    Node cur = head;
    Node mostRight;
    while (cur != null) {
    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.println(cur.value);
    cur = cur.right;
    }
    }

    public static void morrisPre(Node head) {
    Node cur = head;
    Node mostRight;
    while (cur != null) {
    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.println(cur.value);
    cur = cur.left;
    continue;
    } else {
    mostRight.right = null;
    }
    } else {
    System.out.println(cur.value);
    }
    cur = cur.right;
    }
    }

    public static void main(String[] args) {
    Node node = new Node(1);
    node.left = new Node(2);
    node.right = new Node(3);
    node.left.left = new Node(4);
    node.left.right = new Node(5);
    node.right.left = new Node(6);
    node.right.right = new Node(7);
    morris(node);
    System.out.println("=================");
    morrisIn(node);
    System.out.println("=================");
    morrisPre(node);
    }

    /**
    * 二叉树结构
    */
    public static class Node {

    public int value;

    public Node left;

    public Node right;

    public Node(int value) {
    this.value = value;
    }

    }

    }

    /* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */
  • 相关阅读:
    为什么解析 array_column不可用,
    Android经常使用的布局类整理(一)
    C++ Coding Standard
    Kd-Tree算法原理和开源实现代码
    2013年10月5日国庆上班前一天
    2013年10月5日
    2013年10月3日合肥归来
    国庆第二天参加室友婚礼
    国庆随笔
    2013第40周日国庆放假前一天晚上
  • 原文地址:https://www.cnblogs.com/laydown/p/13978700.html
Copyright © 2011-2022 走看看