LeetCode144.二叉树的前序遍历

题目大意:

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

 示例:

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

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

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

 

详解:

首先分析,无论前序中序肯定都是深度优先,采用栈

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

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

  8. 至此结束

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

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode tmp = root;
        while (tmp != null){
            list.add(tmp.val);
            if(tmp.left != null){
                stack.push(tmp);
                tmp = tmp.left;
                continue;
            }
            if(tmp.right != null){
                stack.push(tmp);
                tmp = tmp.right;
                continue;
            }
            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();
            }
        }
        return list;
    }

最后贴一下效率:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值