图的BFS中关于visit访问位置的问题
1, 图的BFS两种代码
1.1,代码1
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int G[1010][1010];
bool visit[1010];
int vex, L;
int height[1010];
void bfs(int root, int &cnt){
queue<int> q;
q.push(root);
height[root]=1;
visit[root]=true; // 1
while(!q.empty()){
int cur = q.front();
q.pop();
int cur_height = height[cur];
if(cur_height<=L+1){
++cnt;
}
for(int v=1;v<=vex;++v){
if(G[cur][v]!=inf&&visit[v]==false){
height[v] = height[cur]+1;
visit[v]=true; // 2
q.push(v);
}
}
}
}
1.2,代码2(这个版本错误)
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
int G[1010][1010];
bool visit[1010];
int vex, L;
// 1: 3 2 3 4±íʾ 1×·2,3,4
int height[1010];
void bfs(int root, int &cnt){
queue<int> q;
q.push(root);
height[root]=1;
while(!q.empty()){
int cur = q.front();
q.pop();
visit[cur]=true; // 3
int cur_height = height[cur];
if(cur_height<=L+1){
++cnt;
}
for(int v=1;v<=vex;++v){
if(G[cur][v]!=inf&&visit[v]==false){
height[v] = height[cur]+1;
q.push(v);
}
}
}
}
2,代码2错误原因分析
代码1成功的防止重复的结点进入队列。 但是代码2没有做到。
举例: 假设有一个含3个结点的环, 标号A,B,C。 遍历顺序按字母大小。
起点是A。
代码1 访问顺序: A->B->C
代码2 访问顺序: A->B->C->C。 // 读者可以简单思考一下
3,小结
上面是图的BFS两种版本代码, 初学者看到这两个版本代码,可能认为是一样的。
笔者也有这样的疑惑。第一次理解后又忘了,第二次思考这个问题忘了没想出来。
所以这里再记录一遍。
像图的BFS遍历是一种非常经典的算法。 也有其成熟的板子。 要记住