一、重拾关键

宽度优先搜索,也有称为广度优先搜索,简称BFS。类似于树的按层次遍历的过程。

初始状态:图G所有顶点均未被访问过,任选一点v。

遍历过程:假设从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先搜索遍历图的过程中以v为起始点,由近至远,依次访问和v有路径相通且路径长度为1,2,…的顶点。

 

二、算法过程

以如下图的无向图G4为例,进行图的宽度优先搜索:

数据结构7——BFS

假设从顶点v1出发进行搜索,首先访问v1和v1的邻接点v2和v3,然后依次访问v2的邻接点v4和v5及v3的邻接点v6和v7,最后访问v4的邻接点v8。由于这些顶点的邻接点均已被访问,并且图中所有顶点都被访问,由些完成了图的遍历。得到的顶点访问序列为:数据结构7——BFS

和深度优先搜索类似,在遍历的过程中也需要一个访问标志数组。并且,为了顺次访问路径长度为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 }
View Code

相关文章:

  • 2021-07-27
  • 2022-12-23
  • 2021-11-30
  • 2022-12-23
  • 2021-05-18
  • 2021-06-12
  • 2022-02-05
  • 2022-02-27
猜你喜欢
  • 2021-11-24
  • 2022-12-23
  • 2021-10-08
  • 2021-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-30
相关资源
相似解决方案