一、BFS算法概述
广度优先搜索的核心思想是从一个起始节点开始,首先访问该节点的所有邻居节点,然后继续访问这些邻居节点的邻居节点,以此类推。BFS算法的一个重要特性是,它会按照从起始节点的“距离”逐层访问节点,这使得它特别适用于寻找最短路径或最小代价的问题。
BFS的基本步骤:
-
初始化:选择一个起始节点,并将其标记为已访问,同时将其放入队列。
-
循环遍历:
- 从队列中取出一个节点。
- 访问该节点的所有未访问的邻居节点,并将它们标记为已访问,然后加入队列。
-
重复步骤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不仅可以解决最短路径问题,还广泛应用于社交网络分析、迷宫问题等领域。