
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
/**
* 方法1:递归
*/
/*
List<Integer> res = new ArrayList<>();
dfs(root, res);
return res;
*/
/**
* 方法2:非递归
*/
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null; // 用于记录前一次访问的节点
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.peek();
// 如果右节点为空 或右节点访问过
if (root.right == null || root.right == pre) {
res.add(root.val); // 此时可以访问根结点
stack.pop();
pre = root;
root = null; // 此时下一轮循环不要将左子树压栈,直接判断栈顶元素
}else {
root = root.right; // 先不出栈 把它右节点入栈
}
}
return res;
/**
* 方法3:非递归的另一种方法
* 修改前序遍历代码中,节点写入结果链表的代码:将插入队尾修改为插入队首
* 修改前序遍历代码中,每次先查看左节点再查看右节点的逻辑:变为先查看右节点再查看左节点
*/
/*
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
while (root != null) {
res.add(0,root.val); // 取根节点的值,插入list最后边
stack.push(root);
root = root.right; // 遍历右子树
}
root = stack.pop();
root = root.left; // 遍历左子树
}
return res;
*/
}
private void dfs(TreeNode root, List<Integer> res) {
if (root == null) return;
dfs(root.left, res); // 左
dfs(root.right, res);// 右
res.add(root.val);// 根
}
}