前言
Node節點
public static class TreeNode {
TreeNode left;
TreeNode right;
int val;
}
定義
- 先序遍歷:先訪問根,再訪問左子樹,最後訪問右子樹
- 中序遍歷:先訪問左子樹,再訪問根,最後訪問右子樹
- 後序遍歷:先訪問左子樹,再訪問右子樹,最後訪問根
遞歸式模板
public static List<Integer> view(TreeNode root, List<Integer> result) {
if(null == root) {
return result;
}
result.add(root.val); // 根
view(root.left, result); // 左
// result.add(root.val);
view(root.right, result); // 右
// result.add(root.val);
return result;
}
由根的訪問時機可以得到不同的遍歷順序,根左右爲先序,左根右爲中序,左右根爲後序
非遞歸式模板
先序、中序
public static List<Integer> view(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (null != cur || !stack.isEmpty()) {
if (null != cur) {
stack.push(cur); // 入棧
result.add(cur.val); // 訪問(先序)
cur = cur.left; // 左行
} else {
cur = stack.pop(); // 出棧
// result.add(cur.val); // 訪問(中序)
cur = cur.right; // 右行
}
}
return result;
}
入棧和左行之間訪問節點,得到的是先序
出棧和右行之間訪問節點,得到的是中序
後序
public static List<Integer> view(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> tmp = new Stack<>(); // 輔助棧
Stack<TreeNode> stack = new Stack<>(); // 主棧
tmp.push(root);
TreeNode cur = null;
while (!tmp.isEmpty()) {
// 從輔助棧取一個節點
cur = tmp.pop();
// 依次將其左右節點入輔助棧
if (null != cur.left) {
tmp.push(cur.left);
}
if (null != cur.right) {
tmp.push(cur.right);
}
// 當前節點入主棧
stack.push(cur);
}
while (!stack.isEmpty()) {
result.add(stack.pop().val);
}
return result;
}
從輔助棧取出一個節點,依次將其左節點–>右節點壓入輔助棧,再將本身壓入主棧,循環至輔助棧空。
最後從主棧取出,根據棧性質易知得到的是左–>右–>根的順序,即爲後序。