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;
    }
}
相关推荐
phltxy6 小时前
C语言操作符详解
java·c语言·算法
aqiu1111117 小时前
【LeetCode 902】最大为 N 的数字组合 - 详细题解与数位组合思路
数据结构·算法·leetcode·蓝桥杯·数位dp
步行cgn7 小时前
@Configuration 详解:Spring 配置类的核心注解
java·后端·spring
sunshine22 girl7 小时前
Java学习一 环境配置2 安装和基本使用Idea
java·学习·intellij-idea
辰烨chenye7 小时前
LeetCode Hot 100 题解 · 哈希篇
算法·leetcode·哈希算法
玖玥拾8 小时前
LeetCode 219 存在重复元素 II
算法·leetcode·哈希算法·散列表
ocean21039 小时前
2025-2026年AI部署与MLOps大厂面试高频问题
人工智能·面试·大模型推理·ai部署
嘿嘿-669 小时前
Windows 一键使用 GPT-6 Astra:Codex CLI 配置教程
java·人工智能·windows·gpt·chatgpt·web
郝学胜-神的一滴9 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生