📅  最后修改于: 2023-12-03 15:40:27.790000             🧑  作者: Mango
在图论中,BFS(Breadth First Search,广度优先搜索)是一种经典的搜索算法,常常用来解决最短路径问题或者搜索状态空间。CLRS(Introduction to Algorithms)是著名的计算机算法教材,其中给出了使用向量和队列的 BFS 算法。
visited
,一个距离数组 distance
,一个前驱结点数组 prev
,一个队列 q
。q
,并将其 visited
标记为已访问。u
,枚举其所有邻接结点 v
。v
未被访问,将其加入队列 q
,并设置其距离为 distance[u] + 1
,前驱结点为 prev[u]
。u
标记为已访问,并将其距离和前驱结点记录到 distance
和 prev
数组中。#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 100; // 最大结点数
vector<int> G[N]; // 图的邻接表表示
int visited[N], distance[N], prev[N]; // 标记数组及前驱结点数组
queue<int> q; // 存储结点的队列
void bfs(int s) { // s 为源结点
fill(visited, visited+N, 0); // 初始化所有结点未被访问
fill(distance, distance+N, -1); // 初始化所有结点距离为 -1(表示不连通)
fill(prev, prev+N, -1); // 初始化所有结点前驱结点为 -1
q.push(s); // 将源结点加入队列
visited[s] = 1; // 标记源结点为已访问
distance[s] = 0; // 源结点距离为 0
while (!q.empty()) { // 队列非空时
int u = q.front(); q.pop(); // 取出队首结点 u
for (int i = 0; i < G[u].size(); i++) { // 枚举结点 u 的邻接结点
int v = G[u][i];
if (!visited[v]) { // 如果结点 v 未被访问
q.push(v); // 将结点 v 加入队列
visited[v] = 1; // 标记结点 v 为已访问
distance[v] = distance[u] + 1; // 结点 v 距离为结点 u 距离加 1
prev[v] = u; // 结点 v 的前驱结点为结点 u
}
}
}
}
int main() {
// 构建图的邻接表表示
G[1].push_back(2);
G[2].push_back(1);
G[1].push_back(3);
G[3].push_back(1);
G[2].push_back(3);
G[3].push_back(2);
G[2].push_back(4);
G[4].push_back(2);
G[3].push_back(4);
G[4].push_back(3);
G[4].push_back(5);
G[5].push_back(4);
bfs(1); // 从结点 1 开始进行 BFS
// 输出所有结点距离及前驱结点
for (int i = 1; i <= 5; i++) {
cout << "distance[" << i << "]=" << distance[i] << ", prev[" << i << "]=" << prev[i] << endl;
}
return 0;
}
该算法使用向量和队列进行实现,具有较好的时间复杂度,是一种经典的 BFS 算法实现方式。在实际应用中,可以通过使用类似 STL 提供的队列等数据结构进行更加方便快捷的实现。