版权声明:本文为博主原创文章,转载请注明出处-- https://blog.csdn.net/qq_38790716/article/details/88066062
广度优先搜索,又称宽度优先搜索,简称 。与深度优先搜索不同的是,广度优先搜索会先将与起始距离较近的点搜索完毕,再继续搜索较远的点,而深搜却是沿一个分支搜到最后
从起点开始,优先搜索离起点最近的点,然后由这个最近的点扩展其他稍近的点,这样一层一层的扩展,就像水波扩散一样。
需要借助队列来实现:
- 1.初始的时候把起始点放入队列中,并标记起点访问
- 2.如果队列不为空,从队列中取出一个元素 ,否则算法结束
- 3.访问和 相连的所有点 ,如果 没有被访问,把 入队,并标记已经访问
- 4.重复执行步骤2
根据该思路可以得出一个简单的代码框架:
void bfs(起始点) {
将起始点放入队列中;
标记起点访问;
while (如果队列不为空) {
访问队列中队首元素x;
删除队首元素;
for (x 所有相邻点) {
if (该点未被访问过且合法) {
将该点加入队列末尾;
}
}
}
队列为空,广搜结束;
}
关于前面所提到的迷宫最短路问题,我们已经学会了使用dfs来求解。用dfs求解迷宫最短路有一个很大的缺点,需要枚举所有可能的路径,读入的地图一旦很大,可能的搜索方案数量就会非常多,用dfs搜索显然效率会非常低。
我们可以借助bfs来求解迷宫游戏。由于bfs是分层搜索,因此,第一次搜索到终点的时候,当前搜索的层数就是最短路径的长度
例1:题目: 迷宫游戏 我们用一个二维的字符数组来表示前面画出的迷宫:
S**. .... ***T
其中字符 表示起点,字符 表示终点,字符 表示墙壁,字符 表示平地。你需要从 出发走到 ,每次只能向上下左右相邻的位置移动,不能走出地图,也不能穿过墙壁,每个点只能通过一次。你需要编程来求解出从起点到终点的最短路径
由于bfs求解要用到队列,所有我们将点的位置设为一个结构体,方便队列存放:
struct node {
int x, y, d;
node (int xx, int yy, int dd) {
x = xx;
y = yy;
d = dd;
}
};
然后套用上述的bfs框架:
int bfs(int sx, int sy) {
//将起始点放入队列中;
queue<node> q;
q.push(node(sx, sy, 0));
//标记起点访问;
vis[sx][sy] = true;
while (!q.empty()){
//访问队列中队首元素x;
node now = q.front();
//删除队首元素;
q.pop();
for (int i = 0; i < 4; ++i) {
int tx = now.x + dir[i][0];
int ty = now.y + dir[i][1];
//该点未被访问过且合法
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
if (maze[tx][ty] == 'T') {
return now.d + 1;
} else {
//将该点加入队列末尾;
vis[tx][ty] = true;
q.push(node(tx, ty, now.d + 1));
}
}
}
}
return -1;
}
完整实现:
#include <iostream>
#include <string>
#include <queue>
using namespace std;
int n,m;
string maze[110];
bool vis[110][110];
int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
bool in(int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m;
}
struct node {
int x, y, d;
node (int xx, int yy, int dd) {
x = xx;
y = yy;
d = dd;
}
};
int bfs(int sx, int sy) {
queue<node> q;
q.push(node(sx, sy, 0));
vis[sx][sy] = true;
while (!q.empty()){
node now = q.front();
q.pop();
for (int i = 0; i < 4; ++i) {
int tx = now.x + dir[i][0];
int ty = now.y + dir[i][1];
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
if (maze[tx][ty] == 'T') {
return now.d + 1;
} else {
vis[tx][ty] = true;
q.push(node(tx, ty, now.d + 1));
}
}
}
}
return -1;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; ++i) {
cin >> maze[i];
}
int x, y;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (maze[i][j] == 'S') {
x = i;
y = j;
}
}
}
cout << bfs(x, y);
return 0;
}
:
5 6
…S*
.…
.….
*….
.T…
:
7