先序遍历:持续深入左子节点,右子节点直接进栈.左子节点为空时,输出当前节点值,开始出栈.
中序遍历:持续深入左子节点,并入栈,直到左子节点为空,输出当前节点值,开始遍历右节点.当前节点为空时,出栈.
后序遍历:如果有一个子节点不为空,且未被遍历过,就入栈当前节点,并一直深入子节点;
若子节点都为空,说明到达了树的底端,输出当前节点,开始出栈.
这是最麻烦的一种遍历,但可以用Set判断一下某节点是否遍历过了,也不算难.
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
public class BinaryTreeTraversal {
//先序遍历
public static void preOrder(TreeNode root) {
TreeNode node = root;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || node != null) {
if (node == null) node = stack.pop();
System.out.print(node.val + " ");
if (node.right != null) stack.push(node.right);
node = node.left;
}
System.out.println();
}
//中序遍历
public static void midOrder(TreeNode root) {
TreeNode node = root;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || node != null) {
if (node == null) {
node = stack.pop();
System.out.print(node.val + " ");
node = node.right;
} else if (node.left == null) {
System.out.print(node.val + " ");
node = node.right;
} else {
stack.push(node);
node = node.left;
}
}
System.out.println();
}
//后序遍历
public static void afterOrder(TreeNode root) {
TreeNode node = root;
Stack<TreeNode> stack = new Stack<>();
Set<TreeNode> set=new HashSet<>();
while (node != null) {
if (node.left != null && !set.contains(node.left)) {
stack.push(node);
node=node.left;
} else if (node.right != null && !set.contains(node.right)) {
stack.push(node);
node=node.right;
} else {
System.out.print(node.val + " ");
set.add(node);
node=stack.isEmpty()?null:stack.pop();
}
}
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.right.right = new TreeNode(6);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.left.left.right = new TreeNode(7);
preOrder(root);
midOrder(root);
afterOrder(root);
}
}
输出:
1 2 4 7 5 3 6
4 7 2 5 1 3 6
7 4 5 2 6 3 1