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;
}