vlambda博客
学习文章列表

二叉树的后序遍历(非递归)

145. 二叉树的后序遍历 【困难题】【后序遍历】

给定一个二叉树,返回它的 后序 遍历。

输入: [1,null,2,3]
1
\
2
/
3

输出: [3,2,1]

题目讲解

解法1:递归

【代码】

List<Integer> list=new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null)
return list;
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
return list;

}

【备注】

  • 这道题是hard的原因是,题目要求我们用非递归的方式做

解法2:非递归一

【数据结构】

【思路】

  • 按照与前序相似的方法(前序压栈的顺序是先右后左,这里是先左后右),先得到一个结果,然后对结果倒序一下

【代码】

 public List<Integer> postOrder2(TreeNode root){
if(root == null)
return new ArrayList<>();
List<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode tmp = stack.pop();
list.add(tmp.val);
if(tmp.left!=null){
stack.push(tmp.left);
}
if(tmp.right!=null){
stack.push(tmp.right);
}
}
Collections.reverse(list);
return list;
}

【备注】

  • 这个解法虽然能得到正确答案,但是这个题解只是能返回遍历的结果,并不是严格意义上树拓扑结构的遍历。虽然结果是正确,但是如果需要按照后续遍历的顺序对树节点进行访问(或操作),此解法就无法满足。

解法2:非递归二

【核心思想】

  • 通过合理地设置入栈出栈的顺序,来达到真正的后序遍历

【数据结构】

【代码】

public List<Integer> postOrder3(TreeNode root) {
List<Integer> ans = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (!stack.isEmpty() || cur != null) {
if (cur != null && cur.left != null) {
stack.push(cur);
TreeNode left = cur.left;
cur.left = null;
cur = left;
} else if (cur != null && cur.right != null) {
stack.push(cur);
TreeNode right = cur.right;
cur.right = null;
cur = right;
} else if (cur.left == null && cur.right == null) {
ans.add(cur.val);
cur = stack.isEmpty() ? null : stack.pop();
}
}
return ans;
}