前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【JavaScript 算法】广度优先搜索:层层推进的搜索策略

【JavaScript 算法】广度优先搜索:层层推进的搜索策略

作者头像
空白诗
发布2024-07-20 12:36:58
500
发布2024-07-20 12:36:58
举报
文章被收录于专栏:【全栈开发之路】

广度优先搜索(Breadth-First Search, BFS)是一种用于遍历或搜索图或树数据结构的算法。该算法从起始节点开始,逐层向外扩展,直到找到目标节点或遍历完所有节点。本文将详细介绍广度优先搜索算法的原理、实现及其应用。


一、算法原理

广度优先搜索的基本思想是从起始节点开始,先访问所有相邻节点,然后再依次访问这些相邻节点的相邻节点,以此类推,层层推进。其基本步骤如下:

  1. 从起始节点开始,将其标记为已访问,并加入队列。
  2. 当队列不为空时,取出队列的头节点,访问该节点的所有相邻节点。
  3. 对于每个相邻节点,如果未被访问过,将其标记为已访问并加入队列。
  4. 重复步骤2和3,直到队列为空或找到目标节点。

二、算法实现

以下是广度优先搜索的JavaScript实现:

代码语言:javascript
复制
/**
 * 广度优先搜索算法
 * @param {Object} graph - 图的邻接表表示
 * @param {string} start - 起始节点
 */
function breadthFirstSearch(graph, start) {
  const queue = [start]; // 初始化队列,将起始节点加入队列
  const visited = new Set(); // 用于记录已访问的节点

  visited.add(start); // 将起始节点标记为已访问

  while (queue.length > 0) {
    const node = queue.shift(); // 取出队列的头节点
    console.log(node); // 访问节点

    // 访问当前节点的所有相邻节点
    for (const neighbor of graph[node]) {
      // 如果相邻节点未被访问过,将其标记为已访问并加入队列
      if (!visited.has(neighbor)) {
        visited.add(neighbor);
        queue.push(neighbor);
      }
    }
  }
}

// 示例图的邻接表表示
const graph = {
  A: ['B', 'C'],
  B: ['D', 'E'],
  C: ['F'],
  D: [],
  E: ['F'],
  F: []
};

// 调用广度优先搜索算法
breadthFirstSearch(graph, 'A'); // 输出: A B C D E F
  1. 函数定义与参数
    • breadthFirstSearch(graph, start):广度优先搜索算法,接受图的邻接表表示和起始节点作为参数。
  2. 初始化队列和已访问节点集合
    • const queue = [start];:初始化队列,将起始节点加入队列。
    • const visited = new Set();:初始化已访问节点集合,用于记录已访问的节点。
  3. 标记起始节点为已访问
    • visited.add(start);:将起始节点标记为已访问。
  4. 遍历队列中的节点
    • while (queue.length > 0):当队列不为空时,继续遍历。
    • const node = queue.shift();:取出队列的头节点。
  5. 访问节点并访问其相邻节点
    • console.log(node);:访问节点,打印节点值。
    • for (const neighbor of graph[node]):遍历当前节点的相邻节点。
    • if (!visited.has(neighbor)):如果相邻节点未被访问过。
    • visited.add(neighbor);:将相邻节点标记为已访问。
    • queue.push(neighbor);:将相邻节点加入队列,等待后续遍历。
  6. 示例图和调用
    • 定义一个示例图的邻接表表示。
    • 调用breadthFirstSearch函数,进行广度优先搜索,并输出结果。

三、应用场景

  1. 最短路径搜索: 广度优先搜索可以用于在无权图中寻找两个节点之间的最短路径。由于BFS逐层遍历,第一次找到目标节点时,即可保证路径是最短的。
  2. 连通性检查: BFS可以用于检查图的连通性,确定图中是否存在路径连接所有节点,并找出所有连通分量。
  3. 层次遍历: BFS在树的层次遍历中有重要应用,可以按层次顺序访问树的节点。
  4. 求解迷宫问题: 在迷宫问题中,BFS可以用于寻找从起点到终点的最短路径,通过逐层扩展,可以找到最短路径解。

四、优化与扩展

  1. 记录路径: 在实际应用中,除了访问节点外,还需要记录从起始节点到每个节点的路径,可以通过在队列中存储路径信息来实现。
代码语言:javascript
复制
/**
 * 广度优先搜索算法(记录路径)
 * @param {Object} graph - 图的邻接表表示
 * @param {string} start - 起始节点
 * @return {Object} - 每个节点的路径
 */
function breadthFirstSearchWithPath(graph, start) {
  const queue = [[start]]; // 初始化队列,队列中存储路径
  const visited = new Set(); // 用于记录已访问的节点

  visited.add(start); // 将起始节点标记为已访问

  while (queue.length > 0) {
    const path = queue.shift(); // 取出队列的头路径
    const node = path[path.length - 1]; // 获取路径中的最后一个节点

    console.log(node); // 访问节点

    // 访问当前节点的所有相邻节点
    for (const neighbor of graph[node]) {
      // 如果相邻节点未被访问过,将其标记为已访问并加入队列
      if (!visited.has(neighbor)) {
        visited.add(neighbor);
        const newPath = [...path, neighbor]; // 创建新的路径
        queue.push(newPath); // 将新路径加入队列
      }
    }
  }
}

// 调用广度优先搜索算法(记录路径)
breadthFirstSearchWithPath(graph, 'A');
  1. 双向广度优先搜索: 对于某些特殊场景,可以使用双向广度优先搜索,同时从起点和终点开始进行BFS,直到两边相遇,从而减少搜索空间,提高效率。

五、总结

广度优先搜索(BFS)是一种用于遍历或搜索图或树数据结构的有效算法。它通过逐层推进的方式,从起始节点开始,先访问所有相邻节点,然后再依次访问这些相邻节点的相邻节点,以此类推,直到找到目标节点或遍历完所有节点。广度优先搜索算法实现简单,适用于最短路径搜索、连通性检查、层次遍历和求解迷宫问题等应用场景。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、算法原理
  • 二、算法实现
  • 三、应用场景
  • 四、优化与扩展
  • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档