從大的層面講,Binary Tree 可以用DFS和BFS。
- 對(duì)于BFS,我們需要 iterative with queue。
- 對(duì)于DFS,Binary Tree 有三種traversal的方式:
** Inorder Traversal: left -> root -> right
** Preoder Traversal: root -> left -> right
** Postoder Traveral: left -> right -> root
記憶方式:order的名字指的是root在什么位置。left,right的相對(duì)位置是固定的。

圖片來源:https://leetcode.com/articles/binary-tree-right-side-view/
對(duì)于時(shí)間復(fù)雜度來說,基本上都是O(n),因?yàn)橐L問所有的點(diǎn)。
對(duì)于空間復(fù)雜度來說,BFS取決于掃描過程中每層的node數(shù),就是樹的寬度,而DFS取決于掃描過程中樹的深度。最壞情況兩個(gè)都是O(n)。
本文重點(diǎn)討論iterative和recursive方法。對(duì)于morris,另開一篇介紹。
Inorder Traversal
首先是recursion寫法,相對(duì)簡(jiǎn)單:
// left->root->right
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.addAll(inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.left));
}
如果用iteration:
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) { // 把左路徑上遇到的點(diǎn)都放進(jìn)stack里面
stack.push(cur);
cur = cur.left;
} // while循環(huán)結(jié)束的時(shí)候,cur==null
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
return res;
}
Preorder Traversal
首先是recursion寫法,相對(duì)簡(jiǎn)單:
// root->left->right
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.add(root.val);
res.addAll(inorderTraversal(root.left));
res.addAll(inorderTraversal(root.left));
}
如果用iteration:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
TreeNode cur = root;
while (!stack.isEmpty()) {
cur = stack.pop();
res.add(cur.val);
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
return res;
}
Postorder Traversal
首先是recursion寫法,相對(duì)簡(jiǎn)單:
// left->right->root
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.addAll(inorderTraversal(root.left));
res.addAll(inorderTraversal(root.left));
res.add(root.val);
}
如果用iteration:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>(); // 便于Insert操作
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
res.add(0, node.val); // 因?yàn)檫@一步,所以轉(zhuǎn)變成了root->right->left
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return res;
}