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 小时前
神经网络入门指南:从 CNN、RNN 到 Attention
人工智能·面试·程序员
Wang's Blog2 小时前
Java 项目实战: 交友项目 - FastDFS:入门案例
java·开发语言·交友
apcipot_rain3 小时前
C++转Java日记(03)
java·开发语言·c++
皮皮林5513 小时前
Java实现微信扫码登录
java
Yyyyyy~5 小时前
【Java】Day4Web基础知识
java·spring boot
2603_969694856 小时前
JDBC 基础学习笔记:API 核心原理解析与 CRUD 代码实操
数据库·笔记·mysql·学习方法·database·sql注入
灿飞屋7 小时前
Kotlin与Java虚拟机三:控制流
android·java·开发语言·后端·python·kotlin·安卓
NE_STOP7 小时前
Spring AI Alibaba - MCP入门
java
nice_lcj5207 小时前
【从零理解 Spring AI · 07】对话记忆:让模型记住上一句说了什么
java·spring ai·ai应用开发·chatmemory·对话记忆
SL_staff8 小时前
制造业交付崩盘?用跨部门节点协同计划打通销售、生产与质量链路
java·开源·产品