先序遍歷:持續深入左子節點,右子節點直接進棧.左子節點爲空時,輸出當前節點值,開始出棧.
中序遍歷:持續深入左子節點,併入棧,直到左子節點爲空,輸出當前節點值,開始遍歷右節點.當前節點爲空時,出棧.
後序遍歷:如果有一個子節點不爲空,且未被遍歷過,就入棧當前節點,並一直深入子節點;
若子節點都爲空,說明到達了樹的底端,輸出當前節點,開始出棧.
這是最麻煩的一種遍歷,但可以用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