A.每日一题:144题+145题 二叉树的前序遍历+后序遍历

题目链接:

144. 二叉树的前序遍历(简单)

145. 二叉树的后序遍历(简单)

算法原理:

Java数据结构------7.二叉树《干货笔记》中二叉树的遍历部分有详解,另外在其中 OJ 面试题部分还有非递归解法(借助栈实现,核心思路见下方代码中的注释部分)

144题:前序遍历

解法一:递归

0ms击败100.00%

时间复杂度O(N)

解法二:栈

1ms击败32.99%

时间复杂度O(N)

145题:后序遍历

解法一:递归

0ms击败100.00%

时间复杂度O(N)

解法二:栈

1ms击败32.99%

时间复杂度O(N)

在这里如果我们只是简单仿照着前序遍历的部分写,会发现出现一些问题👇

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //145. 二叉树的后序遍历
    //解法二:栈
    List<Integer> list=new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root==null) return list;
        Stack<TreeNode> stack=new Stack();
        TreeNode cur=root;
        while(cur!=null||!stack.isEmpty()){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            //由于往左走之后要打印右边
            //所以需要先peek()一下,获取到右边的节点
            //因为弹出去之后,右边的就获取不到了,就丢了
            TreeNode top=stack.peek();
            if(top.right==null){
                list.add(top.val);
                stack.pop();
            }else{
                cur=top.right;
            }
        }
        return list;
    }
}

为什么呢??拿下面这个二叉树距离👇

当代码执行到 D 的时候,会发现:

D 不为空,D 入栈,cur 拿到 D 的左侧,此时栈:A、B、D

top 拿到栈顶 D ,发现 D 的右侧不为空(有个 K ),于是 cur 拿到 K

cur 不为空,K 入栈,cur 拿到 K 的左侧,此时栈:A、B、D、K

cur 为空,top 拿到栈顶 K,发现 K 的右侧为空,打印 K,弹出 K,此时栈顶:A、B、D

再进入循环:重点来了!!

cur 还是空,top 又拿到了栈顶 D,发现 D 的右侧不为空(有个 K )......

于是就在 D 和 K 之间形成了死循环~~

问题就出现在:D 的右边已经打印过了,回到 D 之后又去打印 D 的右边了~~

而当前我们只是处理了 D 的右边为 空才去打印 D 的情况

换句话说,有两种情况下可以打印 D:

1.D 的右边是 空

2.D 的右边被打印过了

因此我们需要记录它的右边是否被打印过了

先初始化 prev 为空

只要 top 被打印了,立马用 prev 指向它,标记已经打印过了

然后在 if 判断条件中,补充上 || top的右边==标记过的 prev

这样就能避免死循环了~~

Java代码:

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //144. 二叉树的前序遍历
    //解法一:递归
    List<Integer> list=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root==null) return list;
        list.add(root.val);
        preorderTraversal(root.left);
        preorderTraversal(root.right);
        return list;
    }
}
java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //144. 二叉树的前序遍历
    //解法二:栈
    List<Integer> list=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root==null) return list;
        //栈的作用:暂存待处理右子树的父节点
        Stack<TreeNode> stack=new Stack();
        TreeNode cur=root;
        //不加cur!=null一开始进不去
        while(cur!=null||!stack.isEmpty()){
            while(cur!=null){
                //不空就入栈,暂存
                stack.push(cur);
                list.add(cur.val);
                //接着前序遍历,往左走
                cur=cur.left;
            }
            //左边空了,就把这个元素弹出来放进top里
            TreeNode top=stack.pop();
            //再去看这个元素的右边
            cur=top.right;
        }
        return list;
    }
}
java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //145. 二叉树的后序遍历
    //解法一:递归
    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;
    }
}
java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //145. 二叉树的后序遍历
    //解法二:栈
    List<Integer> list=new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root==null) return list;
        Stack<TreeNode> stack=new Stack();
        TreeNode cur=root;
        //用 prev 指向刚刚被打印过的点,防止死循环
        TreeNode prev=null;
        while(cur!=null||!stack.isEmpty()){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            //由于往左走之后要打印右边
            //所以需要先peek()一下,获取到右边的节点
            //因为弹出去之后,右边的就获取不到了,就丢了
            TreeNode top=stack.peek();
            if(top.right==null||top.right==prev){
                list.add(top.val);
                stack.pop();
                prev=top;
            }else{
                cur=top.right;
            }
        }
        return list;
    }
}
相关推荐
一勺菠萝丶1 小时前
Maven SNAPSHOT 父 POM 无法解析问题排查
java·maven
少爷晚安。2 小时前
Java基础02_JDK&JRE下载安装及环境配置
java·开发语言
秋波。未央2 小时前
Java Agent 开发 · Day 1 学习笔记(含作业完整标准答案)
java·笔记·学习
何以解忧,唯有..2 小时前
Go语言中的const:常量声明与iota枚举详解
java·开发语言·golang
范什么特西2 小时前
Spring boot细节
java·spring boot·后端
Ysouy2 小时前
Spring Data Elasticsearch 全流程学习教程
java·spring·elasticsearch
沪飘大军2 小时前
goldRush-专门分析黄金的投资理财agent
java·开发语言·elasticsearch
凌波粒2 小时前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
鹏易灵2 小时前
C++——2.常量与 const、constexpr 初识详解
java·开发语言·c++
qq_452396233 小时前
第十三篇:《K8s 安全基础:RBAC、ServiceAccount、Pod Security》
java·安全·kubernetes