相信大家都玩过迷宫游戏,它的游戏规则就是从起点开始出发到达终点。在ACM中,它是一道很好的搜题题,可以用BFS和DFS两种方法解决。接下来我们讨论这两种解法的异同点。
DFS:即深度优先搜索,它的特点是一直递归,直到结束为止。很想像数据结构中的栈。所以,如果用此解法不一定能得到迷宫的最短路径,因为它会把所有可行路径(即能到达终点的)都遍历一遍。特别要注意的是,一定要做好标记,不然在某一点会陷进死循环,然后还要记得回溯,即递归后还原该点为可行点,不然你只能得到唯一一条路径,因为你把到达这条终点的路径封死了,其他路径哪还有机会到达终点。
DFS的优点:
- 所有路径都走一遍;
- 最长路径,最短路径都能找到。
缺点:1、思维难度比BFS大。2、代码相对复杂。
BFS:即广度优先搜索,它的特点是一层层遍历,很像数据结构的队列;一般用此法可以找到问题的最优解,但要注意的是,一定要做好标记,即遍历过的点不能重新入队列了,不然就是死循环。与DFS不同之处在于它不需要回溯,因为它是从某一点一直向外扩展。
BFS的优点:
- 找最最优解;
- 思维难度低。
#include <iostream>
#include <queue>
using namespace std;
struct Node
{
int x, y, step;
Node() : x(0), y(0) {}
Node(int xx, int yy) : x(xx), y(yy) {}
Node(int xx, int yy, int ss) : x(x), y(y), step(ss) {}
};
int map[100][100] = {
{0, 1, 0, 0, 0},
{0, 1, 0, 1, 0},
{0, 0, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 1, 0}};
const int INF = 0x3f3f3f3f;
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
bool vis[100][100] = {false};
Node fa[100][100]; // 记录父节点的属性
queue<Node> qu;
// 判断该点是否能走
bool check(int x, int y)
{
if (x < 0 || x > 4 || y < 0 || y > 4)
return false;
if (vis[x][y] || map[x][y] == 1)
return false;
return true;
}
void output(Node e);
int ans = 0; // 记录路径数
void DFS(Node now)
{
if (now.x == 4 && now.y == 4)
{
ans++;
output(Node(4, 4));
cout << "行走步数:" << now.step << endl;
cout << endl;
return;
}
for (int i = 0; i < 4; i++)
{
int xx = now.x + dir[i][0];
int yy = now.y + dir[i][1];
int ss = now.step + 1;
if (!check(xx, yy))
continue;
vis[xx][yy] = true;
fa[xx][yy] = now;
DFS(Node(xx, yy, ss));
vis[xx][yy] = false;
}
}
void BFS(Node now)
{
qu.push(now);
vis[now.x][now.y] = true;
while (!qu.empty())
{
Node curr = qu.front();
qu.pop();
if (curr.x == 4 && curr.y == 4)
{
output(curr);
return;
}
for (int i = 0; i < 4; i++)
{
int xx = curr.x + dir[i][0];
int yy = curr.y + dir[i][1];
if (!check(xx, yy))
continue;
vis[xx][yy] = true;
fa[xx][yy] = curr; // 指向上一个节点
Node p(xx, yy);
qu.push(p);
}
}
}
// 递归输出路径
void output(Node e)
{
if (e.x == 0 && e.y == 0)
{
cout << "(" << 0 << ", " << 0 << ")->";
return;
}
output(fa[e.x][e.y]);
cout << "(" << e.x << ", " << e.y << ")" << endl;
if (e.x != 4 || e.y != 4)
{
cout << "->";
}
cout << endl;
}
int main()
{
Node b(0, 0, 0);
DFS(b);
return 0;
}