宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止
刚刚开始接触bfs,不是特别懂但是知道了大概思路。先从最基础的问题开始,如下。
迷宫问题
对于迷宫的存储通常采用二维数组的方式,这道题使用字符表示通路与否,所以采用的是字符串数组,在其他情况下可以用0、1表示是否连同,结合一下代码进行分析。
#include<iostream>
#include<queue>
using namespace std;
struct note{
int x, y;
}; //坐标
int book[100][100];//更新步数
int n,m;
char a[100][100];
void findwayout(note Head, note Tail)
{
int currentx, currenty, i;
int Next[4][2]={{1,0},
{0,1},
{-1,0},
{0,-1}}; //四个方向
note head, tail; //出发点 结束点
queue<note> q; //创建队列
q.push(Head);
book[Head.x][Head.y] = 1;
while(!q.empty())
{
head=q.front(); //把开始点赋值给head
q.pop();
for(i=0;i<4;i++)
{
currentx=head.x+Next[i][0];
currenty=head.y+Next[i][1]; //右 上 左 下
if(currentx<0||currenty<0||currenty>m||currentx>n)
continue; //超出地图
if((book[currentx][currenty]==0&&a[currentx][currenty]=='-')||a[currentx][currenty]== 'E') //还未经过这个点并且是通路or这个点是终点
{
tail.x = currentx;
tail.y = currenty;
q.push(tail); //队列的尾巴更新
book[currentx][currenty]=book[head.x][head.y]+1; //矩阵中的可达点步数更新
}
if(currentx==Tail.x&¤ty==Tail.y)
return ;// 找到endpoint 停止循环
}
}
}
int main()
{
int T, i, j;
note head, tail;
cin>>T;
while(T!=0)
{
memset(book, 0, sizeof(book)); //全部填充为0
cin>>n>>m;
for(i = 0;i<n;i++)
{
for(j = 0;j<m;j++)
{
cin>>a[i][j];
if(a[i][j] == 'S')
{
head.x = i;
head.y = j; //标记起点
}
else if(a[i][j] == 'E')
{
tail.x = i;
tail.y = j; //标记终点
}
}
}
findwayout(head,tail);
cout<<book[tail.x][tail.y]-1<<endl;
T--;
}
return 0;
}
1.在main函数中完成矩阵的输入,并设置好起点和终点,矩阵和起点终点可以有两种声明方式,如果在main函数之外声明为全局变量写bfs函数的时候就不用传参了[个人比较喜欢这种]
2.设置结构体来记录每个点的横坐标x和纵坐标y
3.设置book矩阵记录每一点的步数更新情况
4.关键函数体部分:因为找寻路径时分上下左右四个方向,设置Next数组表示移动方向即可。从起始点Head进入队列开始搜索,过程中要考虑 迷宫边界 问题,用for循环直至找到结束点即可。book数据在此过程中不断记录每个点的更新情况。
大致思路就是这样了,需要做更多题练习。