广度优先搜索(BFS)算法解析

96 阅读2分钟

一、BFS算法概述

广度优先搜索的核心思想是从一个起始节点开始,首先访问该节点的所有邻居节点,然后继续访问这些邻居节点的邻居节点,以此类推。BFS算法的一个重要特性是,它会按照从起始节点的“距离”逐层访问节点,这使得它特别适用于寻找最短路径或最小代价的问题。

BFS的基本步骤:

  1. 初始化:选择一个起始节点,并将其标记为已访问,同时将其放入队列。

  2. 循环遍历

    • 从队列中取出一个节点。
    • 访问该节点的所有未访问的邻居节点,并将它们标记为已访问,然后加入队列。
  3. 重复步骤2,直到队列为空,遍历完成。

二、BFS算法的JavaScript实现

1. 图的表示

在编写BFS算法之前,我们首先需要定义一个图。在JavaScript中,图可以使用邻接表的形式表示。邻接表是一个对象,每个顶点(节点)对应一个数组,数组中存储该顶点的所有邻居节点。

class Graph {
  constructor() {
    this.adjList = {};  // 邻接表,存储节点及其邻居
  }

  // 添加节点
  addVertex(vertex) {
    if (!this.adjList[vertex]) {
      this.adjList[vertex] = [];
    }
  }

  // 添加边
  addEdge(vertex1, vertex2) {
    this.addVertex(vertex1);
    this.addVertex(vertex2);
    this.adjList[vertex1].push(vertex2);
    this.adjList[vertex2].push(vertex1);  // 如果是无向图,双向添加边
  }
}

2. BFS算法实现

接下来,我们实现BFS算法。在实现BFS时,我们需要一个队列来存储待访问的节点,并使用一个集合来记录已访问的节点,避免重复访问。

class Graph {
    constructor() {
        this.adjList = {};
    }

    addVertex(vertex) {
        if (!this.adjList[vertex]) {
            this.adjList[vertex] = [];
        }
    }

    addEdge(vertex1, vertex2) {
        this.addVertex(vertex1);
        this.addVertex(vertex2);
        this.adjList[vertex1].push(vertex2);
        this.adjList[vertex2].push(vertex1); // 无向图,双向添加边
    }

    // BFS算法实现
    bfs(startVertex) {
        const visited = new Set(); // 用于存储已访问节点
        const queue = []; // 队列,用于存储待访问的节点
        const result = []; // 记录遍历结果

        // 将起始节点加入队列,并标记为已访问
        queue.push(startVertex);
        visited.add(startVertex);

        while (queue.length > 0) {
            // 从队列中取出节点
            const vertex = queue.shift();
            result.push(vertex); // 访问该节点

            // 遍历当前节点的邻居
            for (const neighbor of this.adjList[vertex]) {
                if (!visited.has(neighbor)) {
                    visited.add(neighbor); // 标记为已访问
                    queue.push(neighbor); // 将邻居加入队列
                }
            }
        }

        return result; // 返回遍历结果
    }
}

// 创建图实例
const graph = new Graph();

// 添加节点和边
graph.addEdge('A', 'B');
graph.addEdge('A', 'C');
graph.addEdge('B', 'D');
graph.addEdge('C', 'E');

// 执行BFS
const bfsResult = graph.bfs('A'); // 从节点'A'开始
console.log(bfsResult); // 输出:['A', 'B', 'C', 'D', 'E']

三、总结

广度优先搜索(BFS)是一种非常高效且常用的图遍历算法。通过队列的方式逐层访问节点,BFS不仅可以解决最短路径问题,还广泛应用于社交网络分析、迷宫问题等领域。