目录
一. BFS原理及操作
广度优先遍历有点类似于之前我们学习过的树的层次遍历,就是要从图的一个顶点出发,依次访问每一层上面的顶点。
首先从图的某一个顶点出发,依次访问该结点的所有邻接点,再按这些邻接点被访问的先后顺序访问与这些邻接点相邻接并且没有被访问过的顶点。重复这个过程,直到所有顶点都被访问过为止。
二. BFS算法的代码实现
算法6.7 按广度优先非递归遍历连通图G
void BFS(Graph G, int v) {
// 按广度优先非递归遍历连通图G
cout << v; // 访问第v个顶点
visited[v] = true; // 标记v为已访问
InitQueue(Q); // 辅助队列Q初始化,置空
EnQueue(Q, v); // v进队
while (!QueueEmpty(Q)) { // 队列非空时继续
DeQueue(Q, u); // 队头元素出队并置为u,注意这里需要修改EnQueue为DeQueue并传入u作为参数
for (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) { // 遍历u的所有邻接顶点
if (!visited[w]) { // 如果w是u的尚未访问的邻接顶点
cout << w; // 访问w顶点
visited[w] = true; // 标记w为已访问
EnQueue(Q, w); // w进队
}
}
} // 结束while循环
} // 结束BFS函数
上面这段代码利用了一个队列作为容器,首先队列中存放一个起始顶点,接着将队头元素出队,这里也就是我们的起始顶点,出队后,将这个出队元素所有未被访问过的邻接点入队。然后重复上面这个过程,只是每次出队的队头元素换了,后面入队和出队的顶点自然也就不一样了。
我们还有个更简洁的BFS算法代码,就是直接遍历邻接表,而不使用上面的FirstAdjVex等等操作。如下所示:
// 更简洁的BFS实现,直接遍历邻接表
void BFS(ALGraph&G, int start) { //邻接表G
InitQueue(Q);
Q.push(start);
visited[start] = true;
while (!Q.empty()) {
int u = Q.front();
Q.pop();
cout << u << " ";
for (int w : G[u]) { // 直接遍历顶点u的邻接顶点
if (!visited[w]) {
Q.push(w);
visited[w] = true;
// 可以选择在这里输出w,但通常我们只在访问时输出一次
}
}