二叉树遍历(非递归,非栈)
package tree.morris;
import tree.TreeNode;
import java.util.ArrayList;
import java.util.List;
/**
* 二叉树遍历:非递归,不用栈,O(1)
* <p>
* {link https://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html} 原版使用 C 编写
*/
public class MorrisTraversal {
/**
* 中序遍历(左中右)--> 二叉查找树,可得到顺序数列
*/
public static <E> List<E> inorderTraversal(TreeNode<E> root) {
List<E> rs = new ArrayList<>();
TreeNode<E> cur = root;
TreeNode<E> prev = null;
while (cur != null) {
if (cur.getLeft() == null) {
rs.add(cur.getValue());
cur = cur.getRight();
} else {
// find predecessor
prev = cur.getLeft();
while (prev.getRight() != null
&& prev.getRight() != cur) {
prev = prev.getRight();
}
if (prev.getRight() == null) {
prev.setRight(cur);
cur = cur.getLeft();
} else {
prev.setRight(null);
rs.add(cur.getValue());
cur = cur.getRight();
}
}
}
return rs;
}
public static <E> List<E> preorderTraversal(TreeNode<E> root) {
List<E> rs = new ArrayList<>();
TreeNode<E> cur = root;
TreeNode<E> prev = null;
while (cur != null) {
if (cur.getLeft() == null) {
rs.add(cur.getValue());
cur = cur.getRight();
} else {
prev = cur.getLeft();
while (prev.getRight() != null
&& prev.getRight() != cur) {
prev = prev.getRight();
}
if (prev.getRight() == null) {
rs.add(cur.getValue());
prev.setRight(cur);
cur = cur.getLeft();
} else {
prev.setRight(null);
cur = cur.getRight();
}
}
}
return rs;
}
public static <E> List<E> postorderTraversal(TreeNode<E> root) {
List<E> rs = new ArrayList<>();
TreeNode<E> dump = new TreeNode<>(null);
dump.setLeft(root);
TreeNode<E> cur = dump;
TreeNode<E> prev = null;
while (cur != null) {
if (cur.getLeft() == null) {
cur = cur.getRight();
} else {
prev = cur.getLeft();
while (prev.getRight() != null
&& prev.getRight() != cur) {
prev = prev.getRight();
}
if (prev.getRight() == null) {
prev.setRight(cur);
cur = cur.getLeft();
} else {
printReverse(rs, cur.getLeft(), prev); // call print
prev.setRight(null);
cur = cur.getRight();
}
}
}
return rs;
}
private static <E> void printReverse(List<E> rs, TreeNode from, TreeNode<E> to) {
reverse(from, to);
TreeNode<E> p = to;
while (true) {
rs.add(p.getValue());
if (p == from) {
break;
}
p = p.getRight();
}
reverse(to, from);
}
private static <E> void reverse(TreeNode from, TreeNode<E> to) {
if (from == to) {
return;
}
TreeNode<E> x = from;
TreeNode<E> y = from.getRight();
TreeNode<E> z = null;
while (true) {
z = y.getRight();
y.setRight(x);
x = y;
y = z;
if (x == to) {
break;
}
}
}
}