LeetCode145.二叉树的后序遍历

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

示例:

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

输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

详解:

这道题和我的上两篇二叉树的前序遍历二叉树的中序遍历很像,遍历思想是一样的,关键是什么时候输出结果。

  1. 首先new一个列表(存储结果),new一个栈, 定义一个当前待处理的节点(初始值为root节点)
  2. 判断当前节点是否为空,为空退出循环,不为空执行第3步。因为是后序遍历,所以当前节点也不能直接输入到结果(和前序不一样的地方
  3. 判断左子节点,不为空,压栈,更新当前节点,执行第2步
  4. 判断右子节点,不为空,压栈,更新当前节点,执行第2步。
  5. 这一步分析比较长,写成一段(这一步遍历思想和中序的很像,直接拷贝过来,改一下细节):
  6. 如果执行到了这里,说明当前节点的左右子节点都是空的,但当前节点还没有输出到结果,且还没有压栈,直接将当前节点输出到结果。(这个时候已经就没有压栈的必要了,因为没有子节点,也已经输出了结果)。这个时候就要考虑他的父节点了,父节点在哪呢?栈里!可以看到上面先执行第三步,那么每一个父节点如果他有左节点,那么他的右节点就没有遍历处理(因为随着循环去处理他的左节点了)。所以现在要依次考虑每一个父节点右子节点(此时不需要考虑父节点的左子节点,不理解的自己去面壁思考)

    既然依次考虑,所以需要一个循环,如果当前栈顶节点的右子节点不为空,且右子节点不等于当前节点(这个且非常重要,不然就可能会重复处理右子节点),说明当前右子节点还没有处理,更新当前节点,退出循环,执行第2步。否则直接出栈当前节点,且输出当前节点(因为此时说明已经处理完他的左右子节点),接着判断下一个栈顶,直到栈空了

  7. 至此结束

再详细的思路也不及代码片行,那直接贴代码:

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode tmp = root;
        while (tmp != null){
            if(tmp.left != null){
                stack.push(tmp);
                tmp = tmp.left;
                continue;
            }
            if(tmp.right != null){
                stack.push(tmp);
                tmp = tmp.right;
                continue;
            }
            list.add(tmp.val);
            while (true){
                if(stack.isEmpty()){
                    tmp = null;
                    break;
                }
                TreeNode peek = stack.peek();
                if(peek.right != null && peek.right != tmp){
                    tmp = peek.right;
                    break;
                }
                tmp = stack.pop();
                list.add(tmp.val);
            }
        }
        return list;
    }

最后贴效率:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值