宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。简单来说,bfs好像是一个耳听六路眼观八方的人,搜索时是一层一层的搜索的。BFS利用的数据结构是queue,空间复杂度为o(2^n),另外BFS可以用来解决最短路问题。BFS是一个从近到远的扩散过程。
从初始状态S开始,利用规则,生成所有可能的状态。构成树的下一层节点,检查是否出现目标状态G,若未出现,就对该层所有状态节点,分别顺序利用规则。生成再下一层的所有状态节点,对这一层的所有状态节点检查是否出现G,若未出现,继续按上面思想生成再下一层的所有状态节点,这样一层一层往下展开。直到出现目标状态为止。
可以分为四个步骤:初始化(初始化队列和所求的值) -> 判空取队头(判断是否为空并取出队头) -> 拓展(利用队头去扩展) -> 判断入队(如果符合,将该点入队)。
void bfs(){
queueq;
q.push(初始位置);
//初始化
while(q.size()){
int t = q.front();
q.pop();//取出队头的点,用该点向周围扩散。
if(check(j)){ //如果该点可行就将它加入队列中
q.psuh(j);
//实施相应的操作
}
}
}
好人何老板
题目描述
八十高龄的邓大爷在大街上摔倒了,因为众所周知的原因围观的路人都不敢去救助。恰好何老板下班路过,一向助人为乐的他赶紧抱起邓大爷往医院跑。但好心的何老板面临着一个问题,城市里面有很多医院,到底哪家医院最近呢? 城市地图用一个由数字0,1,2,3构成的n*m矩阵表示(n,m<=1000)。数字0表示可以行走的道路或空地。数字1表示邓大爷摔倒的位置。数字2表示不可通过的建筑物或障碍物。数字3表示医院。 何老板只能延上下左右四个方向移动,每走一步的距离是1。问到最近的医院需要走多少步?(地图中至少有一个可到达的医院)
输入格式
第一行,两个空格间隔的整数n和m
接下来是一个n*m的矩阵,用空格做间隔
输出格式
一个整数,表示最小的步数。
样例输入
5 8
3 0 0 0 0 2 0 3
2 0 0 2 3 0 2 0
0 2 0 2 0 3 0 2
0 1 0 2 0 0 0 0
0 0 0 0 0 0 0 3
样例输出
6
思路:每次向四个方向搜索,第一个找到的就是最短的方案
没找到就把当前位置设置为2,并继续寻找
代码如下:
#include
#include
using namespace std;
int n,m,c[1010][1010];
int k,l;
struct node{
int x,y,s;
node(int x_,int y_,int s_){
x=x_;
y=y_;
s=s_;
}
};
int bfs(int x,int y){
queue f;
f.push(node(x,y,0));
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
while(f.size()){
node a=f.front();
f.pop();
for(int i=0;i<4;i++){
node b(a.x+dx[i],a.y+dy[i],a.s+1);
if(b.x>0&&b.x<=n&&b.y>0&&b.y<=m){
if(c[b.x][b.y]==3){
return b.s;
}
if(c[b.x][b.y]==0){
c[b.x][b.y]=2;
f.push(b);
}
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&c[i][j]);
if(c[i][j]==1){
k=i,l=j;
}
}
}
cout<
特性:
空间复杂度
因为所有节点都必须被储存,因此BFS的空间复杂度为 O(|V| + |E|),其中 |V| 是节点的数目,而 |E| 是图中边的数目。注:另一种说法称BFS的空间复杂度为 O(BM),其中 B 是最大分支系数,而 M 是树的最长路径长度。由于对空间的大量需求,因此BFS并不适合解非常大的问题。
时间复杂度
最差情形下,BFS必须寻找所有到可能节点的所有路径,因此其时间复杂度为 O(|V| + |E|),其中 |V| 是节点的数目,而 |E| 是图中边的数目。
最佳解 若所有边的长度相等,广度优先搜索算法是最佳解——亦即它找到的第一个解,距离根节点的边数目一定最少;但对一般的图来说,BFS并不一定回传最佳解。这是因为当图形为加权图 (亦即各边长度不同)时,BFS仍然回传从根节点开始,经过边数目最少的解;而这个解距离根节点的距离不一定最短。这个问题可以使用考虑各边权值,BFS的改良算法成本一致搜寻法(en:uniform-cost search)来解决。然而,若非加权图形,则所有边的长度相等,BFS就能找到最近的最佳解。
广度优先搜索算法能用来解决图论中的许多问题,例如: