二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归

🏠个人主页:得鹿梦鱼

🎬作者简介:C/C++/JAVA后端开发学习者

❄️个人专栏:C语言数据结构(C语言)EasyX

❄️个人专栏:JAVA SE数据结构与算法(JAVA)

❄️个人专栏:游戏规划程序人生

✨ 从来绝巘须孤往,万里同尘即玉京

### 文章目录

  • @[TOC] ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/52e50c884e354014bce988b00f9960d2.png#pic_center) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 📝 文章说明 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 一、二叉树的前序遍历(LeetCode 144) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 1. 思路一:遍历思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 2. 思路二:分治思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 3. 思路三:非递归(栈模拟法) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 二、二叉树的中序遍历(LeetCode 94) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 1. 思路一:遍历思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 2. 思路二:分治思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 3. 思路三:非递归(栈模拟法) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 三、二叉树的后序遍历(LeetCode 145) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 1. 思路一:遍历思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 2. 思路二:分治思想 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 3. 思路三:非递归(栈模拟法) 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • 🎯 核心总结 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)
  • ✍️ 写在最后 🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归 📝 文章说明 一、二叉树的前序遍历(LeetCode 144) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 二、二叉树的中序遍历(LeetCode 94) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 三、二叉树的后序遍历(LeetCode 145) 1. 思路一:遍历思想 2. 思路二:分治思想 3. 思路三:非递归(栈模拟法) 🎯 核心总结 ✍️ 写在最后)

🌳二叉树遍历:LeetCode 144 / 94 / 145 之递归 + 分治 + 非递归


📝 文章说明

本文针对二叉树前序、中序、后序遍历 三大核心题型,提供三种通用解题思路

  1. 遍历思想(递归)
  2. 分治思想(递归)
  3. 非递归(栈模拟)

所有代码均可直接提交 LeetCode,层次清晰、易学易记。


一、二叉树的前序遍历(LeetCode 144)

给你二叉树的根节点 root,返回它节点值的前序遍历。

遍历规则:根 → 左 → 右

1. 思路一:遍历思想

  • 思路:递归遍历整棵树,边遍历边记录结果
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> result = new ArrayList<>();
    
    public List<Integer> preorderTraversal(TreeNode root) {
        if (root == null) {
            return result;
        }
        // 根
        result.add(root.val);
        // 左
        preorderTraversal(root.left);
        // 右
        preorderTraversal(root.right);
        return result;
    }
}

2. 思路二:分治思想

  • 思路:把问题拆分,先处理左子树、再处理右子树,最后合并结果
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        // 根
        result.add(root.val);
        // 左子树结果
        List<Integer> leftResult = preorderTraversal(root.left);
        result.addAll(leftResult);
        // 右子树结果
        List<Integer> rightResult = preorderTraversal(root.right);
        result.addAll(rightResult);
        
        return result;
    }
}

3. 思路三:非递归(栈模拟法)

  • 思路:利用栈模拟递归,右先入栈、左后入栈,保证左先执行
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        
        Deque<TreeNode> stack = new ArrayDeque<>();
        stack.push(root);
        
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            
            // 右先入栈
            if (node.right != null) {
                stack.push(node.right);
            }
            // 左后入栈
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return result;
    }
}

二、二叉树的中序遍历(LeetCode 94)

给你二叉树的根节点 root,返回它节点值的中序遍历。

遍历规则:左 → 根 → 右

1. 思路一:遍历思想

  • 思路:递归走到最左,回溯时记录根节点,再进入右子树
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> result = new ArrayList<>();
    
    public List<Integer> inorderTraversal(TreeNode root) {
        if (root == null) {
            return result;
        }
        // 左
        inorderTraversal(root.left);
        // 根
        result.add(root.val);
        // 右
        inorderTraversal(root.right);
        return result;
    }
}

2. 思路二:分治思想

  • 思路:先拿到左子树结果 → 加入根 → 加入右子树结果
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        // 左
        List<Integer> leftResult = inorderTraversal(root.left);
        result.addAll(leftResult);
        
        // 根
        result.add(root.val);
        
        // 右
        List<Integer> rightResult = inorderTraversal(root.right);
        result.addAll(rightResult);
        
        return result;
    }
}

3. 思路三:非递归(栈模拟法)

  • 思路:
    ① 一路向左,全部入栈
    ② 出栈时访问
    ③ 转向右子树
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        
        Deque<TreeNode> stack = new ArrayDeque<>();
        TreeNode cur = root;
        
        while (cur != null || !stack.isEmpty()) {
            if (cur != null) {
                // 一路向左
                stack.push(cur);
                cur = cur.left;
            } else {
                // 出栈 + 访问
                cur = stack.pop();
                result.add(cur.val);
                // 向右
                cur = cur.right;
            }
        }
        return result;
    }
}

三、二叉树的后序遍历(LeetCode 145)

给你二叉树的根节点 root,返回它节点值的后序遍历。

遍历规则:左 → 右 → 根

1. 思路一:遍历思想

  • 思路:先遍历左、再遍历右,最后记录根节点
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> result = new ArrayList<>();
    
    public List<Integer> postorderTraversal(TreeNode root) {
        if (root == null) {
            return result;
        }
        // 左
        postorderTraversal(root.left);
        // 右
        postorderTraversal(root.right);
        // 根
        result.add(root.val);
        return result;
    }
}

2. 思路二:分治思想

  • 思路:合并左、右结果,最后加入根节点
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        // 左
        List<Integer> leftResult = postorderTraversal(root.left);
        result.addAll(leftResult);
        // 右
        List<Integer> rightResult = postorderTraversal(root.right);
        result.addAll(rightResult);
        // 根
        result.add(root.val);
        
        return result;
    }
}

3. 思路三:非递归(栈模拟法)

  • 思路:前序(根 → 左 → 右) → 改为(根 → 右 → 左) → 最后反转得到后序
  • 代码实现
java 复制代码
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        
        Deque<TreeNode> stack = new ArrayDeque<>();
        stack.push(root);
        
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            
            // 左先入栈
            if (node.left != null) {
                stack.push(node.left);
            }
            // 右后入栈
            if (node.right != null) {
                stack.push(node.right);
            }
        }
        // 反转:根 → 右 → 左  → 左 → 右 → 根
        Collections.reverse(result);
        return result;
    }
}

🎯 核心总结

  1. 前序:根 → 左 → 右
  2. 中序:左 → 根 → 右
  3. 后序:左 → 右 → 根

通用技巧:

  • 递归最简单,适合快速写题
  • 分治思想适合理解二叉树结构
  • 非递归用栈,面试高频考点

✍️ 写在最后

这三篇遍历是二叉树所有题目的基础骨架

掌握这三种写法,二叉树的绝大多数题目都能轻松上手。

下一篇:层序遍历、对称二叉树、翻转二叉树、路径总和等高频真题。

相关推荐
凌波粒2 小时前
LeetCode--347.前 K 个高频元素(栈和队列)
java·数据结构·算法·leetcode
GLPerryHsu2 小时前
jar包的快速修改和重新发布
java·jar
FluxMelodySun2 小时前
机器学习(三十二) 半监督学习-基于分歧的方法与半监督聚类
人工智能·算法·机器学习
steem_ding2 小时前
C++ 回调函数详解
开发语言·c++·算法
会编程的土豆2 小时前
字符串知识(LCS,LIS)区分总结归纳
开发语言·数据结构·c++·算法
程序员老邢2 小时前
【技术底稿 14】通用文件存储组件:SpringBoot 自动装配 + 多存储适配
java·spring boot·后端·阿里云·微服务·策略模式
北顾笙9802 小时前
day25-数据结构力扣
数据结构·算法·leetcode
zjneymar2 小时前
苍穹外卖中一些知识点和问题
java·linux·服务器
Rsun045512 小时前
5、Java 原型模式从入门到实战
java·开发语言·原型模式