宽搜(BFS)
①.所谓宽度优先搜索
宽度优先搜索算法(又称广度优先搜索)是很麻烦最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
翻译过来就是:
宽度优先搜索是一种粗暴的算法,就像走迷宫时,dfs是一个人在走迷宫,而bfs是一群人在走迷宫,而且每个人都有一部手机(既然有手机那为什么不sos?,那么就可以分成几队,同时朝不同方向展开搜索,如果遇到岔路继续分队,直到找到出口位置
dfs注重于深度,也就是一条路走到头,而bfs注重宽度,也就是说什么也不管,先把这条路上所有岔路口都占了
bfs常用于求最短路径,路径总数等
bfs建立在队列的基础上
dfs建立在递归的基础上
两者都需要用到树
如图
dfs路径是
1——2——1——3——5——6——5——8——5——3——7——9——7——3——1——4
而bfs的路径是
1——2——3——4(只有3有岔路口——3——5——7——6——8——9
因为bfs不需要回溯,所以步骤比dfs短些
——————————————————————————————————————————————————————————————————————————
②算法过程
1 void bfs() 2 { 3 f=r=1;//队列初始化为空 4 que[r]=初始状态 //队尾插入初始状态 5 while(f<=r){ 6 //当队列非空时做,其中f和r分别表示队列的头指针和尾指针 7 if(找到目标状态) 8 做相应处理(如退出循环输出解、输出当前解、比较解的优劣) 9 else{ 10 获取头结点信息; 11 拓展头结点; 12 if(拓展出当新结点没有出现过){ 13 r++; 14 将新结点插到队尾; 15 } 16 } 17 f++;//取下一结点 18 } 19 }
③例题
迷宫问题(一本通):http://ybt.ssoier.cn:8088/problem_show.php?pid=1255
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int mp[10][10]; 4 int f,r; 5 struct group{ 6 int x; 7 int y; 8 int father; 9 }que[100]; 10 int father[100],b; 11 int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; 12 void pr(int p){ 13 if(p==0)return ; 14 pr(que[p].father); 15 cout<<"("<<que[p].x<<", "<<que[p].y<<")"<<endl; 16 } 17 void pr2() 18 { 19 for(int i=f; i ; i=que[i].father) 20 cout<<"("<<que[i].x<<", "<<que[i].y<<")"<<endl; 21 } 22 void bfs(){ 23 f=r=1; 24 que[r].x=0; 25 que[r].y=0; 26 que[r].father=0; 27 mp[0][0]=1; 28 while(f<=r){ 29 group t; 30 t.x=que[f].x; 31 t.y=que[f].y; 32 if(t.x==4&&t.y==4){ 33 pr(f); 34 } 35 for(int i=0;i<4;i++){ 36 int lx=t.x+next[i][0]; 37 int ly=t.y+next[i][1]; 38 if(lx>=0 && lx<5 && ly>=0 && ly<5 && mp[lx][ly]==0){ 39 mp[lx][ly]=1; 40 r++; 41 que[r].x=lx; 42 que[r].y=ly; 43 que[r].father=f; 44 45 } 46 } 47 f++; 48 } 49 } 50 int main(){ 51 for(int i=0;i<5;i++){ 52 for(int j=0;j<5;j++){ 53 cin>>mp[i][j]; 54 } 55 } 56 bfs(); 57 return 0; 58 }