# **广度优先搜索** ## **广度优先搜索的过程** 广度优先搜索算法(又称宽度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。 Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。 ​ 广度优先算法的核心思想是:从初始节点开始,应用算符生成第一层节点,检查目标节点是否在这些后继节点中,若没有,再用产生式规则将所有第一层的节点逐一扩展,得到第二层节点,并逐一检查第二层节点中是否包含目标节点。若没有,再用算符逐一扩展第二层的所有节点……,如此依次扩展,检查下去,直到发现目标节点为止。即 1. 从图中的某一顶点V0开始,先访问V0; 2. 访问所有与V0相邻接的顶点V1,V2,......,Vt; 3. 依次访问与V1,V2,......,Vt相邻接的所有未曾访问过的顶点; 4. 循此以往,直至所有的顶点都被访问过为止。 ​ 这种搜索的次序体现沿层次向横向扩展的趋势,所以称之为广度优先搜索。 ## **广度优先搜索算法描述:** ``` c int Bfs() { 初始化,初始状态存入队列; 队列首指针head=0; 尾指针tail=1; do { 指针head后移一位,指向待扩展结点; for (int i=1;i<=max;++i) //max为产生子结点的规则数 { if (子结点符合条件) { tail指针增1,把新结点存入列尾; if (新结点与原已产生结点重复) 删去该结点(取消入队,tail减1); else if (新结点是目标结点) 输出并退出; } } }while(head #include using namespace std; int ju[9][9]={{0,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,1,1}, {0,0,1,1,1,1,0,1,1}, {0,0,1,1,0,0,1,1,1}, {0,0,1,0,1,1,1,0,1}, {0,1,1,0,1,1,1,0,0}, {0,0,0,1,1,1,1,1,0}, {0,1,1,1,0,0,1,1,0}, {0,1,1,1,1,0,0,0,1}}; int a[101],b[101]; bool s[9]; //初始化 int out(int d) //输出过程 { cout< using namespace std; int dx[4]={-1,0,1,0}, dy[4]={0,1,0,-1}; int bz[100][100],num=0,n,m; void doit(int p,int q) { int x,y,t,w,i; int h[1000][10]; num++;bz[p][q]=0; t=0;w=1;h[1][1]=p;h[1][2]=q; //遇到的第一个细胞入队 do { t++; //队头指针加1 for (i=0;i<=3;i++) //沿细胞的上下左右四个方向搜索细胞 { x=h[t][1]+dx[i];y=h[t][2]+dy[i]; if ((x>=0)&&(x=0)&&(y using namespace std; int n,m,desx,desy,soux,souy,totstep,a[51],b[51],map[51][51]; bool f; int move(int x, int y,int step) { map[x][y]=step; //走一步,作标记,把步数记下来 a[step]=x; b[step]=y; //记路径 if ((x==desx)&&(y==desy)) { f=1; totstep=step; } else { if ((y!=m)&&(map[x][y+1]==0)) move(x,y+1,step+1); //向右 if ((!f)&&(x!=n)&&(map[x+1][y]==0)) move(x+1,y,step+1); //往下 if ((!f)&&(y!=1)&&(map[x][y-1]==0)) move(x,y-1,step+1); //往左 if ((!f)&&(x!=1)&&(map[x-1][y]==0)) move(x-1,y,step+1); //往上 } } int main() { int i,j; cin>>n>>m; //n行m列的迷宫 for (i=1;i<=n;i++) //读入迷宫,0表示通,-1表示不通 for (j=1;j<=m;j++) cin>>map[i][j]; cout<<"input the enter:"; cin>>soux>>souy; //入口 cout<<"input the exit:"; cin>>desx>>desy; //出口 f=0; //f=0表示无解;f=1表示找到了一个解 move(soux,souy,1); if (f) { for (i=1;i<=totstep;i++) //输出直迷宫的路径 cout< using namespace std; int u[5]={0,0,1,0,-1}, w[5]={0,1,0,-1,0}; int n,m,i,j,desx,desy,soux,souy,head,tail,x,y,a[51],b[51],pre[51],map[51][51]; bool f; int print(int d) { if (pre[d]!=0) print (pre[d]); //递归输出路径 cout<>n>>m; //n行m列的迷宫 for (i=1;i<=n;i++) //读入迷宫,0表示通,-1表示不通 for (j=1;j<=m;j++) cin>>map[i][j]; cout<<"input the enter:"; cin>>soux>>souy; //入口 cout<<"input the exit:"; cin>>desx>>desy; //出口 head=0; tail=1; f=0; map[soux][souy]=-1; a[tail]=soux; b[tail]=souy; pre[tail]=0; while (head!=tail) //队列不为空 { head++; for (i=1;i<=4;i++) //4个方向 { x=a[head]+u[i]; y=b[head]+w[i]; if ((x>0)&&(x<=n)&&(y>0)&&(y<=m)&&(map[x][y]==0)) { //本方向上可以走 tail++; a[tail]=x; b[tail]=y; pre[tail]=head; map[x][y]=-1; if ((x==desx)&&(y==desy)) //扩展出的结点为目标结点 { f=1; print(tail); break; } } } if (f) break; } if (!f) cout<<"no way."<