
访问一个节点:
-
一直往左走
-
到最左节点
-
输出
-
回到父节点
-
去右边
class Solution {
public List<Integer> inorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root; while(cur != null || !stack.isEmpty()){ // 1. 一直向左走 while(cur != null){ stack.push(cur); cur = cur.left; } // 2. 弹出节点访问 cur = stack.pop(); ans.add(cur.val); // 3. 转向右子树 cur = cur.right; } return ans; }}

那么栈应该模拟:
-
访问节点
-
保存右节点
-
去左边
-
左边结束,再去右边
class Solution {
public List<Integer> preorderTraversal(TreeNode root) { List<Integer> ans = new ArrayList<>(); if(root == null){ return ans; } Stack<TreeNode> stack = new Stack<>(); // 根节点入栈 stack.push(root); while(!stack.isEmpty()){ // 弹出节点 TreeNode node = stack.pop(); // 访问根 ans.add(node.val); // 注意顺序 // 栈后进先出 // 所以右边先入栈 if(node.right != null){ stack.push(node.right); } // 左边后入栈 if(node.left != null){ stack.push(node.left); } } return ans; }}

前序:
根 左 右
如果改一下:
先:
根 右 左
然后反转:
左 右 根
也就是后序。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root == null){
return ans;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
// 先加入结果
ans.add(node.val);
// 左先入
if(node.left != null){
stack.push(node.left);
}
// 右后入
if(node.right != null){
stack.push(node.right);
}
}
// 反转结果
Collections.reverse(ans);
return ans;
}
}