Morris遍历笔记

Morris遍历笔记

空间复杂度为O(1)

树的Morris遍历的过程:

设置当前节点为cur,一开始当前节点cur来到了,整棵树的头结点

分为两种情况:

1)、cur节点无左树,处理方式 cur = cur.right;当前节点移向右节点。

2)、cur节点有左树,处理方式 找到左树的最右边的节点,设置为mostRight;

​ 1、 当mostRight节点的右指针为null

​ mostRight.right = cur; (mostRight的右指针指向当前节点cur)
​ cur = cur.left;(当前节点cur左移)

​ 2、 mostRight节点的右指针不为null

​ mostRight.right = null ;

​ cur = cur.right;(当前指针cur右移)

    public static class Node {
        public int value;
        Node left;
        Node right;

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

// Morris遍历中非叶子节点都会遍历两次
    public static void morris(Node head) {
        Node cur = head;
        Node mostRight;
        while (cur != null) {
            // cur 有左树 找到左树最右边的节点,设置为mostRight
            mostRight = cur.left;
            if (mostRight != null) {
                // 找到cur左树上,最真实的的最右节点
                while (mostRight.right != null && mostRight.right != cur) {
                    mostRight = mostRight.right;
                }
                // 最右边的节点的右指针 为空
                if (mostRight.right == null) {
                    mostRight.right = cur;
                    // 第一次的时候
                    System.out.print(cur.value +" ");
                    cur = cur.left;
                    continue;
                } else {
                    // mostRight.right == null 一定 mostRight.right == cur
                    mostRight.right = null;
                }
            }
            // 第二次的时候
            System.out.print(cur.value +" ");
            cur = cur.right;
        }
    }
    /**
     * 中序
     *
     * @param head
     */
    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.print(cur.value + " ");
            cur = cur.right;
        }
    }

    /**
     * 先序遍历
     *
     * @param head
     */
    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.print(cur.value + " ");
                    cur = cur.left;
                    continue;
                } else {
                    mostRight.right = null;
                }
            } else {
                System.out.print(cur.value + " ");
            }
            cur = cur.right;
        }
    }
   /**
     * 后序遍历
     *
     * @param head
     */
    private static void morrisPos(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;
                    printEdge(cur.left);
                }
            }
            cur = cur.right;
        }
        printEdge(head);
    }

    /**
     * 逆序打印右边界
     *
     * @param head
     */
    private static void printEdge(Node head) {
        Node cur = reverseEdge(head);
        while (cur != null) {
            System.out.print(cur.value + " ");
            cur = cur.right;
        }
        reverseEdge(head);
    }

    /**
     * 反转链表
     *
     * @param from
     * @return
     */
    private static Node reverseEdge(Node from) {
        Node pre = null;
        Node next;
        while (from != null) {
            next = from.right;
            from.right = pre;
            pre = from;
            from = next;
        }
        return pre;
    }

    /**
     * 判断是否是搜索二叉树
     *
     * @param head
     * @return
     */
    private static boolean isBST(Node head) {

        Node cur = head;
        Node mostRight;
        // 前一个的节点的值
        Integer pre = null;
        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 + "");
            // 如果  前一个数的值 大于当前的  返回false
            if (pre != null && pre >= cur.value) {
                return false;
            }
            pre = cur.value;
            cur = cur.right;
        }
        return true;
    }

    /**
     *   找到分支中最矮的高度
     * @param head
     * @return
     */
    public static int minHerght2(Node head) {
        if (head == null) {
            return 0;
        }
        Node cur = head;
        Node mostRight;
        int curLevel = 0;
        int minHeight = Integer.MAX_VALUE;
        while (cur != null) {
            mostRight = cur.left;
            if (mostRight != null) {
                int rightBoardSize = 1;
                while (mostRight.right != null && mostRight.right != cur) {
                    rightBoardSize++;
                    mostRight = mostRight.right;
                }
                // 第一次到达
                if (mostRight.right == null) {
                    curLevel++;
                    mostRight.right = cur;
                    cur = cur.left;
                    continue;
                } else {
                    // 第二次到达
                    if (mostRight.left == null) {
                        minHeight = Math.min(minHeight, curLevel);
                    }
                    curLevel -= rightBoardSize;
                    mostRight.right = null;
                }
                // 只有一次的到达
            } else {
                curLevel++;
            }
            cur = cur.right;
        }
        int finalRight = 1;
        cur = head;
        while (cur.right != null) {
            finalRight++;
            cur = cur.right;
        }
        if (cur.left == null) {
            minHeight = Math.min(minHeight, finalRight);
        }
        return minHeight;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值