【LeetCode】二叉树的后序遍历(递归,迭代)

目录

题目要求:给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

方法一:递归

方法二:迭代

思路分析:

代码展示:

复杂度分析

方法三:迭代进阶

思路分析:

代码展示:


题目要求:给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

示例 1:

输入:root = [1,null,2,3]
输出:[3,2,1]

 

方法一:递归

递归的方法和二叉树的前序以及中序遍历在之前的博客中已经写过,需要的小伙伴可以点击链接查看

递归求二叉树的前中后序遍历

【LeetCode】二叉树的前序遍历(递归,迭代,Morris遍历)

【LeetCode】二叉树的中序遍历(递归,迭代,Morris遍历)

这篇文章主要来讲解非递归的方法对二叉树进行后序遍历

方法二:迭代

思路分析:


迭代的方式其实与递归是等价的,区别在于递归的时候隐式地维护了一个栈,而我们在迭代的时候

需要显式地将这个栈模拟出来,其余的实现与细节都相同,具体可以参考下面的代码

其实后序遍历的思想与中序遍历大差不差,只不过中序是左根右,在栈中弹出的元素其左子树都是已访问完的,此时我们可以直接访问该节点,再继续访问它的右子树就是了

后续遍历是左右根,此时我们只能保证该节点的左子树访问完成,但却不知晓右子树的情况,此时我们只需维护一个节点,用来帮助我们判断该节点的右子树有没有被访问过即可

代码展示:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        //栈和线性表
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        TreeNode prev = null;
        while(root != null || !stack.isEmpty()){
            //root非空
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            //此时root为空,我们需要判断右子树是否走过或者为空
            root = stack.pop();
            if(root.right == null || root.right == prev){
                list.add(root.val);
                prev = root;
                root = null;
            }else{
                stack.push(root);
                root = root.right;
            }
        }
        return list;
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树的节点数。每一个节点恰好被遍历一次。

  • 空间复杂度:O(n),为迭代过程中显式栈的开销,平均情况下为 O(log⁡n),最坏情况下树呈现链状,为 O(n)

方法三:迭代进阶

思路分析:

我们都知道前序遍历与后序遍历的差别就是根的位置的关系

前序遍历顺序为:根 -> 左 -> 右

后序遍历顺序为:左 -> 右 -> 根

如果我们用链表来存储节点,并且改为头插的方式,那么按照前序遍历的结果

链表就变为了:右 -> 左 -> 根

我们将遍历的顺序由从左到右修改为从右到左

结果链表就变为了:左 -> 右 -> 根,这刚好就是后序遍历的结果

代码展示:

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode x = stack.pop();
            list.add(0,x.val);
            if(x.right != null){
                stack.push(x.right);
            }
            if(x.left != null){
                stack.push(x.left);
            }
        }
        return list;
    }
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值