import java.io.*;import java.util.*;public classMain {public static void main(String[] args) throwsIOException {
BufferedReader br= new BufferedReader(newInputStreamReader(System.in));
br.readLine();
TreeNode root=createTreeNode(br);
preOrderMorris(root);
inOrderMorris(root);
postOrderMorris(root);
br.close();
}/*** Morris 遍历算法整体步骤如下(假设当前遍历到的节点为 xx):
* 如果 xx 无左孩子,则访问 xx 的右孩子,即 x = x.right。
* 如果 xx 有左孩子,则找到 xx 左子树上最右的节点(即左子树中序遍历的最后一个节点,xx 在中序遍历中的前驱节点),我们记为predecessor。根据predecessor 的右孩子是否为空,进行如下操作。
* 如果 predecessor 的右孩子为空,则将其右孩子指向 xx,然后访问 xx 的左孩子,即 x = x.left。
* 如果 predecessor 的右孩子不为空,则此时其右孩子指向 xx,说明我们已经遍历完 xx 的左子树,我们将predecessor 的右孩子置空,
然后访问 xx 的右孩子,即 x = x.right。
* 作者:LeetCode-Solution
* 链接:https://leetcode-cn.com/problems/recover-binary-search-tree/solution/hui-fu-er-cha-sou-suo-shu-by-leetcode-solution/* 来源:力扣(LeetCode)
* 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
**/
//先序遍历 Morris遍历 莫里斯遍历
private static voidpreOrderMorris(TreeNode root) {if (null ==root) {return;
}
TreeNode cur= root, predecessor = null;while (null !=cur) {
predecessor=cur.left;if (null !=predecessor) {while (null != predecessor.right && cur !=predecessor.right) {
predecessor=predecessor.right;
}if (null ==predecessor.right) {
predecessor.right=cur;
System.out.print(cur.val+ " ");
cur=cur.left;continue;
}else{
predecessor.right= null;
}
}else{
System.out.print(cur.val+ " ");
}
cur=cur.right;
}
System.out.println();
}//中序遍历 morris遍历, 复用空指针指向上层某个节点//这里为左子树最右结点指向根结点
private static voidinOrderMorris(TreeNode root) {if (null ==root) {return;
}
TreeNode cur= root, predecessor = null;while (null !=cur) {
predecessor=cur.left;if (null !=predecessor) {//获取左子树上的最右结点
while (null != predecessor.right && cur !=predecessor.right) {
predecessor=predecessor.right;
}if (null ==predecessor.right) {//左子树上的最右结点 指向当前结点
predecessor.right =cur;
cur=cur.left;continue; //注意这里的continue;
} else{//复原空指针
predecessor.right = null;
}
}
System.out.print(cur.val+ " ");
cur=cur.right;
}
System.out.println();return;
}//后序遍历 morris遍历
private static voidpostOrderMorris(TreeNode root) {if (null ==root) {return;
}
TreeNode cur= root, prodecessor = null;while (null !=cur) {
prodecessor=cur.left;if (null !=prodecessor) {while (null != prodecessor.right && cur !=prodecessor.right) {
prodecessor=prodecessor.right;
}if (null ==prodecessor.right) {
prodecessor.right=cur;
cur=cur.left;continue; //这里的continue;
} else{
prodecessor.right= null;
printEdge(cur.left);
}
}
cur=cur.right;
}
printEdge(root);
System.out.println();
}private static voidprintEdge(TreeNode root) {//逆序右边界
TreeNode tail =reverseEdge(root);
TreeNode cur=tail;while (null !=cur) {
System.out.print(cur.val+ " ");
cur=cur.right;
}
reverseEdge(tail);
}private staticTreeNode reverseEdge(TreeNode from) {
TreeNode next= null, pre = null;while (null !=from) {
next=from.right;
from.right=pre;
pre=from;
from=next;
}returnpre;
}private static TreeNode createTreeNode(BufferedReader br) throwsIOException {
String[] rawInput= br.readLine().trim().split(" ");int rootVal = Integer.parseInt(rawInput[0]);int leftVal = Integer.parseInt(rawInput[1]);int rightVal = Integer.parseInt(rawInput[2]);
TreeNode root= newTreeNode(rootVal);if (0 !=leftVal) {
root.left=createTreeNode(br);
}if (0 !=rightVal) {
root.right=createTreeNode(br);
}returnroot;
}
}classTreeNode {intval;
TreeNode left;
TreeNode right;public TreeNode(intval) {this.val =val;
}public TreeNode(intval, TreeNode left, TreeNode right) {this.val =val;this.left =left;this.right =right;
}
}