前端算法面试难点解析:二叉树遍历的四种经典方式

前端算法面试难点解析:二叉树遍历的四种经典方式

frontend-hard-mode-interview 《前端内参》,有关于JavaScript、编程范式、设计模式、软件开发的艺术等大前端范畴内的知识分享,旨在帮助前端工程师们夯实技术基础以通过一线互联网企业技术面试。 frontend-hard-mode-interview 项目地址: https://gitcode.com/gh_mirrors/fr/frontend-hard-mode-interview

二叉树是前端面试中经常遇到的算法考点,掌握其遍历方式是必备技能。本文将深入解析二叉树的前序、中序、后序和层序遍历,帮助前端开发者攻克这一面试难点。

二叉树遍历基础概念

二叉树遍历是指按照某种顺序访问树中的所有节点,确保每个节点都被访问且仅被访问一次。根据访问顺序的不同,主要分为四种遍历方式:

  1. 前序遍历:根节点 → 左子树 → 右子树
  2. 中序遍历:左子树 → 根节点 → 右子树
  3. 后序遍历:左子树 → 右子树 → 根节点
  4. 层序遍历:从上到下、从左到右逐层访问

前序遍历详解

算法原理

前序遍历遵循"根左右"的顺序:

  1. 首先访问根节点
  2. 然后递归遍历左子树
  3. 最后递归遍历右子树

递归实现

function preorderTraversal(root) {
    let result = [];
    function traverse(node) {
        if (!node) return;
        result.push(node.val);    // 访问根节点
        traverse(node.left);      // 遍历左子树
        traverse(node.right);     // 遍历右子树
    }
    traverse(root);
    return result;
}

迭代实现(栈模拟)

function preorderTraversal(root) {
    if (!root) return [];
    let stack = [root];
    let result = [];
    while (stack.length) {
        const node = stack.pop();
        result.push(node.val);
        // 注意:先压右节点,再压左节点
        if (node.right) stack.push(node.right);
        if (node.left) stack.push(node.left);
    }
    return result;
}

中序遍历详解

算法原理

中序遍历遵循"左根右"的顺序:

  1. 先递归遍历左子树
  2. 然后访问根节点
  3. 最后递归遍历右子树

递归实现

function inorderTraversal(root) {
    let result = [];
    function traverse(node) {
        if (!node) return;
        traverse(node.left);      // 遍历左子树
        result.push(node.val);    // 访问根节点
        traverse(node.right);     // 遍历右子树
    }
    traverse(root);
    return result;
}

迭代实现

function inorderTraversal(root) {
    let stack = [];
    let result = [];
    let curr = root;
    while (curr || stack.length) {
        while (curr) {
            stack.push(curr);
            curr = curr.left;    // 一直向左走到底
        }
        curr = stack.pop();
        result.push(curr.val);   // 访问节点
        curr = curr.right;       // 转向右子树
    }
    return result;
}

后序遍历详解

算法原理

后序遍历遵循"左右根"的顺序:

  1. 先递归遍历左子树
  2. 然后递归遍历右子树
  3. 最后访问根节点

递归实现

function postorderTraversal(root) {
    let result = [];
    function traverse(node) {
        if (!node) return;
        traverse(node.left);      // 遍历左子树
        traverse(node.right);     // 遍历右子树
        result.push(node.val);    // 访问根节点
    }
    traverse(root);
    return result;
}

迭代实现

function postorderTraversal(root) {
    if (!root) return [];
    let stack = [root];
    let result = [];
    while (stack.length) {
        const node = stack.pop();
        result.unshift(node.val);  // 从前面插入,实现逆序
        if (node.left) stack.push(node.left);
        if (node.right) stack.push(node.right);
    }
    return result;
}

层序遍历详解

算法原理

层序遍历又称广度优先遍历(BFS),按照树的层级从上到下、从左到右依次访问每个节点。通常使用队列来实现。

实现代码

function levelOrder(root) {
    if (!root) return [];
    let queue = [root];
    let result = [];
    while (queue.length) {
        let levelSize = queue.length;
        let currentLevel = [];
        for (let i = 0; i < levelSize; i++) {
            const node = queue.shift();
            currentLevel.push(node.val);
            if (node.left) queue.push(node.left);
            if (node.right) queue.push(node.right);
        }
        result.push(currentLevel);
    }
    return result;
}

遍历方式对比与应用场景

| 遍历方式 | 顺序 | 典型应用场景 | |---------|------|------------| | 前序遍历 | 根左右 | 复制二叉树、表达式树的前缀表示 | | 中序遍历 | 左根右 | 二叉搜索树的有序输出 | | 后序遍历 | 左右根 | 删除二叉树、表达式树的后缀表示 | | 层序遍历 | 按层 | 计算二叉树深度、寻找最短路径 |

面试常见问题

  1. 递归与迭代的选择:递归代码简洁但可能有栈溢出风险;迭代更可控但代码复杂
  2. 时间复杂度:所有遍历方式都是O(n),n为节点数
  3. 空间复杂度:最坏情况下都是O(n),平均情况下递归为O(h),h为树高

掌握这四种遍历方式不仅能帮助通过面试,更是理解树结构操作的基础。建议读者动手实现每种遍历,并尝试解决相关变种题目,如锯齿形层序遍历、N叉树遍历等。

frontend-hard-mode-interview 《前端内参》,有关于JavaScript、编程范式、设计模式、软件开发的艺术等大前端范畴内的知识分享,旨在帮助前端工程师们夯实技术基础以通过一线互联网企业技术面试。 frontend-hard-mode-interview 项目地址: https://gitcode.com/gh_mirrors/fr/frontend-hard-mode-interview

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

解银旦Fannie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值