BFS思想
-
方法:
从图的某一结点出发,首先依次访问该结点的所有邻接点 V i 1 , V i 2 , ⋯   , V i n Vi_1,Vi_2,\cdots,Vi_n Vi1,Vi2,⋯,Vin再按这些顶点被访问的先后次序依次访问与它们相邻接的所有未被访问过的点。
重复此过程,直至所有顶点均被访问为止。 -
例子:
BFS——邻接表实现
因为图的BFS的实实现过程与树的层次遍历很相似,所以可以通过队列来实现。
- 具体过程:
1.假设从v1顶点开始,将0号位置(v1结点在邻接表中的0号位置)入队,如下图,
2.将V1出队,将V1的邻接点入队,查找邻接表,发现V1的邻接点是V2和V3,即将1号位置和2号位置入队,
3.将V2出队,将V2的邻接点入队,查找邻接表,发现V2的邻接点是V1,V4和V5,因为V1已经访问过,所以将V4和V5入队,即将3号位置和4号位置入队,
4.将V3出队,将V3的邻接点入队,查找邻接表,发现V2的邻接点是V1,V6和V7,因为V1已经访问过,所以将V6和V7入队,即将5号位置和6号位置入队,
5.将V4出队,将V4的邻接点入队,查找邻接表,发现V4的邻接点是V2和V8,因为V2已经访问过,所以将V8入队,即将7号位置入队,
5.将V5出队,将V5的邻接点入队,查找邻接表,发现V4的邻接点是V2和V8,因为V2和V8都已经访问过,所以将V8不需要入队,
6.重复上述步骤,发现所有的顶点都访问过了,此时队列为空,结束遍历。
- 算法描述:
void BFS(Graph G, int v)
{
cout << v;
visited[v] = true; //访问第v个顶点
InitQueue(Q); //队列Q初始化,置空
EnQueue(Q, v); //v进队
while (!QueueEmpty(Q)) //队列非空
{
DeQueue(Q, u); //队头元素出队并置u
for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
if (!visited[w]) //w为u尚未访问的邻接顶点
{
cout << w; //w进队
visited[w] = true;
EnQueu(Q, w);
}
}
}
如果使用邻接矩阵,则BFS对于每一个被访问到的顶点,都要循环检测矩阵中的整整一行,总的时间复杂度为 O ( n 2 ) O(n^2) O(n2)
用邻接表来表示图,虽然有2e个表结点,但只需扫描e个结点即可完成遍历,加上访问n个头结点的时间,时间复杂度为 O ( n + e ) O(n+e) O(n+e)。