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

}

}

/* 如有意见或建议,欢迎评论区留言;如发现代码有误,欢迎批评指正 */