JavaScript实现二叉树所有路径的DFS遍历 | 代码示例与解释

2025/3/15
本文介绍了如何使用JavaScript实现二叉树的深度优先搜索(DFS)遍历,以找到从根节点到叶子节点的所有路径。通过代码示例和详细解释,帮助读者理解算法的实现过程及其时间复杂度分析。
二叉树结构图,显示根节点、左子树、右子树和叶子节点的路径

在二叉树中,所有路径指的是从根节点到叶子节点的路径。我们可以使用深度优先搜索(DFS)来遍历二叉树,并记录每条路径。以下是使用JavaScript实现的代码示例:

class TreeNode {
    constructor(val, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

function binaryTreePaths(root) {
    const paths = [];

    function dfs(node, path) {
        if (!node) return;

        // 将当前节点的值加入路径
        path += node.val;

        // 如果是叶子节点,将路径加入结果集
        if (!node.left && !node.right) {
            paths.push(path);
            return;
        }

        // 递归遍历左子树和右子树
        path += '->';
        dfs(node.left, path);
        dfs(node.right, path);
    }

    dfs(root, '');
    return paths;
}

// 示例用法
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.right = new TreeNode(5);

console.log(binaryTreePaths(root)); // 输出: ["1->2->5", "1->3"]

代码解释:

  1. TreeNode类:定义了二叉树的节点结构,每个节点包含一个值 val,以及指向左子树和右子树的指针 leftright

  2. binaryTreePaths函数:这是主函数,用于找到二叉树的所有路径。

    • paths 数组用于存储所有路径。
    • dfs 函数是一个递归函数,用于深度优先遍历二叉树。
    • dfs 函数中,我们首先检查当前节点是否为空。如果为空,则返回。
    • 然后将当前节点的值加入路径 path
    • 如果当前节点是叶子节点(即没有左子树和右子树),则将当前路径加入 paths 数组。
    • 如果不是叶子节点,则在路径后添加 ->,然后递归遍历左子树和右子树。
  3. 示例用法:创建了一个简单的二叉树,并调用 binaryTreePaths 函数来获取所有路径。

输出:

对于给定的二叉树:

    1
   / \
  2   3
   \
    5

输出结果为:

["1->2->5", "1->3"]

这个算法的时间复杂度是 O(N),其中 N 是二叉树中的节点数,因为我们需要访问每个节点一次。空间复杂度也是 O(N),主要是递归调用栈的空间消耗。

上次更新:

相关文章

npx完全指南:前端开发必备工具详解 | 20年架构师深度解析

本文由20年前端架构师深入解析npx工具,涵盖其核心功能、优势、高级用法、最佳实践及与npm/yarn的区别比较,帮助开发者掌握这一现代前端开发利器。

·前端开发

Astro 静态站点生成器:构建高性能网站的最佳选择

Astro 是一个专注于构建快速、轻量级网站的静态站点生成器,支持多种前端框架,采用岛屿架构减少 JavaScript 加载,提升性能。

·前端开发

MySQL JSON数据类型支持与使用指南 | 详细解析与示例

本文详细解析了MySQL从5.7版本开始支持的JSON数据类型,包括版本支持、创建JSON字段、插入与查询JSON数据、修改JSON数据、生成JSON、索引优化、性能与应用场景、注意事项及示例全流程。

·后端开发

Weex 跨平台移动开发框架:核心特性与使用指南

Weex 是由阿里巴巴开源的跨平台移动开发框架,支持使用 Vue.js 或 Rax 构建高性能的 iOS、Android 和 Web 应用。本文详细解析了 Weex 的核心特性、架构、工作流程、组件和模块、开发工具、优缺点、应用场景及未来发展。

·前端开发

ECharts 与 DataV 数据可视化工具对比分析 | 选择指南

本文详细对比了 ECharts 和 DataV 两个常用的数据可视化工具,包括它们的设计目标、优缺点、使用场景和技术栈,帮助读者根据具体需求选择合适的工具。

·前端开发

前端部署后通知用户刷新页面的常见方案 | 单页应用更新提示

本文介绍了在前端部署后通知用户刷新页面的几种常见方案,包括WebSocket实时通知、轮询检查版本、Service Worker版本控制、版本号对比、自动刷新、使用框架内置功能以及第三方库。每种方案的优缺点和示例代码均有详细说明。

·前端开发

TypeScript 映射类型常见问题与解决方案 | 提升代码维护性

本文探讨了在使用 TypeScript 时,映射类型的不当使用可能导致的问题,如代码难以维护、类型推断不准确或性能问题,并提供了相应的解决方案和最佳实践。

·编程语言

TypeScript 交叉类型与联合类型:区别与最佳实践

本文详细解释了 TypeScript 中交叉类型(Intersection Types)和联合类型(Union Types)的区别,提供了使用场景、类型守卫、避免过度使用交叉类型的建议,以及如何通过工具辅助解决混淆问题。

·编程语言

TypeScript 类继承中的常见类型问题及解决方案 | TypeScript 开发指南

本文详细探讨了在 TypeScript 中使用类继承时可能遇到的常见类型问题,包括类型兼容性、构造函数、方法重写、访问修饰符、泛型类继承、抽象类以及类型断言等问题,并提供了相应的解决方案和代码示例。

·编程语言

TypeScript 函数重载:常见问题与解决方案

本文探讨了 TypeScript 中函数重载的常见问题,包括签名与实际实现不匹配、重载签名过多、与泛型结合时的类型推断问题等,并提供了相应的解决方案。

·编程语言