LeetCode94. 二叉树的中序遍历|递归与迭代双解法详解

2 阅读2分钟

前言

二叉树遍历是算法入门必刷基础题,中序遍历遵循「左子树→根节点→右子树」的访问规则,是二叉搜索树有序输出的核心逻辑。本文以 LeetCode 第 94 题为载体,用 JavaScript 实现递归、栈迭代两种主流解法,拆解思路与优劣,适合前端算法入门读者。

题目分析

给定二叉树根节点root,返回中序遍历结果数组。示例输入:root = [1,null,2,3],二叉树结构为根 1、右子节点 2、2 的左子节点 3;按照左→根→右规则遍历,输出[1,3,2]。边界场景:空树返回空数组、单节点树返回仅含节点值的数组。

解法一:递归(简洁直观,入门首选)

核心思路

递归天然符合深度优先遍历逻辑,递归终止条件:当前节点为空直接返回。执行顺序固定:递归左子树 → 记录当前节点值 → 递归右子树。

完整代码

javascript

运行

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
var inorderTraversal = function(root) {
    const res = [];
    const dfs = (node) => {
        if (!node) return;
        dfs(node.left);
        res.push(node.val);
        dfs(node.right);
    }
    dfs(root);
    return res;
};

优缺点

优势:代码仅十余行,逻辑零理解成本,快速通过测试用例;劣势:依赖函数调用栈,树深度极大时会触发栈溢出,面试中大数据场景不推荐。

解法二:栈迭代(面试高频,规避递归溢出)

核心思路

手动用数组模拟递归调用栈,指针持续遍历左节点并入栈,无左节点时弹出栈顶记录数值,再切换处理右子树,循环直至指针为空且栈无元素。

完整代码

javascript

运行

var inorderTraversal = function(root) {
    const res = [];
    const stack = [];
    let cur = root;
    while (cur || stack.length) {
        // 遍历至最左侧叶子节点
        while (cur) {
            stack.push(cur);
            cur = cur.left;
        }
        cur = stack.pop();
        res.push(cur.val);
        // 处理右子树
        cur = cur.right;
    }
    return res;
};

执行流程示例(样例树)

  1. cur=1,入栈,cur 指向 null;
  2. 弹出 1,存入结果,cur 切换至右节点 2;
  3. cur=2 入栈,cur 指向左节点 3;
  4. cur=3 入栈,cur 指向 null;
  5. 弹出 3 存入结果,cur 为 null;
  6. 弹出 2 存入结果,cur 为 null;循环结束,输出[1,3,2]

两种方案对比总结

  1. 递归:适合刷题快速解题、理解遍历逻辑,深度过大会栈溢出;
  2. 栈迭代:无递归深度限制,时间复杂度 O (n)、空间 O (n),面试官更爱考察。

结尾

二叉树前、中、后序遍历逻辑相通,仅调整节点记录顺序。吃透中序迭代写法,能快速举一反三掌握另外两种遍历,为二叉搜索树、路径求和等中等难度题目打好基础。