一、重拾关键
宽度优先搜索,也有称为广度优先搜索,简称BFS。类似于树的按层次遍历的过程。
初始状态:图G所有顶点均未被访问过,任选一点v。
遍历过程:假设从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先搜索遍历图的过程中以v为起始点,由近至远,依次访问和v有路径相通且路径长度为1,2,…的顶点。
二、算法过程
以如下图的无向图G4为例,进行图的宽度优先搜索:
假设从顶点v1出发进行搜索,首先访问v1和v1的邻接点v2和v3,然后依次访问v2的邻接点v4和v5及v3的邻接点v6和v7,最后访问v4的邻接点v8。由于这些顶点的邻接点均已被访问,并且图中所有顶点都被访问,由些完成了图的遍历。得到的顶点访问序列为:。
和深度优先搜索类似,在遍历的过程中也需要一个访问标志数组。并且,为了顺次访问路径长度为2、3、…的顶点,需附设队列以存储已被访问的路径长度为1、2、… 的顶点。
三、代码实现
邻接矩阵做存储结构时,广度优先搜索的代码如下。
/* 图的BFS遍历 */
//邻接矩阵形式实现
//顶点从1开始
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn = 105; //最大顶点数
typedef int VertexType; //顶点类型
bool vis[maxn];
struct Graph{ //邻接矩阵表示的图结构
VertexType vex[maxn]; //存储顶点
int arc[maxn][maxn]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
};
void createGraph(Graph &g) //构建有向网g
{
cout<<"请输入顶点数和边数:";
cin>>g.vexnum>>g.arcnum;
//构造顶点向量
cout<<"请依次输入各顶点:\n";
for(int i=1;i<=g.vexnum;i++){
scanf("%d",&g.vex[i]);
}
//初始化邻接矩阵
for(int i=1;i<=g.vexnum;i++){
for(int j=1;j<=g.vexnum;j++){
g.arc[i][j] = 0;
}
}
//构造邻接矩阵
VertexType u,v; //分别是一条弧的弧尾(起点)和弧头(终点)
printf("每一行输入一条弧依附的顶点(空格分开):\n");
for(int i=1;i<=g.arcnum;i++){
cin>>u>>v;
g.arc[u][v] = g.arc[v][u] = 1;
}
}
//邻接矩阵的宽度遍历操作
void BFSTraverse(Graph g)
{
queue<int> q; //声明队列q
for(int i=1;i<=g.vexnum;i++){
vis[i] = false;
}
for(int i=1;i<=g.vexnum;i++){ //对每个顶点做循环
if(!vis[i]){
vis[i] = true;
printf("%d\t",g.vex[i]);
q.push(i); //将此节点入队列
while(!q.empty()){
int m = q.front();
q.pop(); //出队列,值已赋给m
for(int j=1;j<=g.vexnum;j++){
if(g.arc[m][j]==1 && !vis[j]){ //如果顶点j是顶点i的未访问的邻接点
vis[j] = true;
printf("%d\t",g.vex[j]);
q.push(j); //将顶点j入队列
}
}
}
}
}
}
int main()
{
Graph g;
createGraph(g);
BFSTraverse(g);
return 0;
}
我的代码2:
1 int n, m; 2 int graph[105][105]; 3 bool vis[105]; 4 queue<int> q; 5 6 void init() 7 { 8 memset(map,0,sizeof(map)); 9 memset(vis,0,sizeof(vis)); 10 while(!q.empty()) q.pop(); 11 } 12 13 void BFS(int u) 14 { 15 vis[u] = 1; 16 cout<<u<<"\t"; 17 q.push(u); 18 while(!q.empty()){ 19 int p = q.front(); 20 q.pop(); 21 for(int i=1;i<=n;i++){ 22 if(!vis[i] && graph[p][i]==1){ 23 q.push(i); 24 cout<<i<<"\t"; 25 vis[i] = 1; 26 } 27 } 28 } 29 } 30 31 void read() 32 { 33 init(); 34 cin>>n>>m; 35 for(int i=1;i<=m;i++){ 36 int u, v; 37 cin>>u>>v; 38 graph[u][v] = graph[v][u] = 1; 39 } 40 for(int i=1;i<=n;i++){ 41 if(!vis[i]) 42 BFS(i); 43 } 44 cout<<endl; 45 } 46 47 int main() 48 { 49 read(); 50 return 0; 51 }