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

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;
}

【备注】

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

【核心思想】

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

【数据结构】

【代码】

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;
}

关注微信公众号“算法岗从零到无穷”,更多算法知识点告诉你。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值