C++ 迷宫求解:使用栈和队列寻找最短路径
C++ 迷宫求解:使用栈和队列寻找最短路径
本文将介绍如何使用 C++ 实现迷宫求解算法,并使用栈和队列两种数据结构来寻找从起点到终点的最短路径。
算法实现
该算法基于深度优先搜索 (DFS) 和广度优先搜索 (BFS) 两种策略,分别使用栈和队列来存储待探索的节点。
数据结构
Node: 表示迷宫中的一个节点,包含坐标 (x, y) 和到达该节点的方向 (dir)。maze: 表示迷宫地图,用 1 表示可通行区域,用 0 表示障碍物。visited: 表示已经访问过的节点,用 true 表示已访问,用 false 表示未访问。dx和dy: 用于表示移动方向的数组。
算法步骤
- 初始化迷宫和访问矩阵。
- 使用栈或队列存储起点节点。
- 循环遍历队列或栈中的节点,直到找到终点节点或所有节点都被访问过。
- 从当前节点向四个方向探索新的节点,如果新的节点有效且未被访问,则将其加入队列或栈中。
- 当找到终点节点时,输出从起点到终点的路径。
代码实现
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
struct Node {
int x, y, dir;
Node(int _x, int _y, int _dir) : x(_x), y(_y), dir(_dir) {}
};
// 定义方向常量
const int RIGHT = 1;
const int DOWN = 2;
const int LEFT = 3;
const int UP = 4;
// 定义迷宫和访问矩阵
int maze[101][101];
bool visited[101][101];
// 定义移动方向数组
int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {0, 0, 1, 0, -1};
// 定义迷宫的行数和列数
int M, N;
// 判断坐标是否有效
bool isValid(int x, int y) {
return x >= 1 && x <= M && y >= 1 && y <= N && maze[x][y] == 1 && !visited[x][y];
}
// 输出路径
void printPath(int start_x, int start_y, int end_x, int end_y) {
stack<Node> s;
s.push(Node(end_x, end_y, 0));
while (!s.empty()) {
Node currentNode = s.top();
s.pop();
int x = currentNode.x;
int y = currentNode.y;
int dir = currentNode.dir;
cout << '(' << x << ',' << y << ',' << dir << ')';
if (s.size() % 5 == 0) {
cout << endl;
} else if (!s.empty()) {
cout << ',';
}
for (int i = 1; i <= 4; i++) {
int new_x = x + dx[i];
int new_y = y + dy[i];
if (isValid(new_x, new_y)) {
visited[new_x][new_y] = true;
s.push(Node(new_x, new_y, i));
break;
}
}
}
}
// 使用栈寻找最短路径
bool findShortestPath(int start_x, int start_y, int end_x, int end_y) {
stack<Node> s;
s.push(Node(start_x, start_y, 0));
visited[start_x][start_y] = true;
while (!s.empty()) {
Node currentNode = s.top();
s.pop();
int x = currentNode.x;
int y = currentNode.y;
int dir = currentNode.dir;
if (x == end_x && y == end_y) {
printPath(start_x, start_y, end_x, end_y);
return true;
}
for (int i = dir + 1; i <= 4; i++) {
int new_x = x + dx[i];
int new_y = y + dy[i];
if (isValid(new_x, new_y)) {
visited[new_x][new_y] = true;
s.push(Node(new_x, new_y, 0));
break;
}
}
}
return false;
}
// 使用队列确定最短路径
bool findShortestPathBFS(int start_x, int start_y, int end_x, int end_y) {
queue<Node> q;
q.push(Node(start_x, start_y, 0));
visited[start_x][start_y] = true;
while (!q.empty()) {
Node currentNode = q.front();
q.pop();
int x = currentNode.x;
int y = currentNode.y;
int dir = currentNode.dir;
if (x == end_x && y == end_y) {
printPath(start_x, start_y, end_x, end_y);
return true;
}
for (int i = 1; i <= 4; i++) {
int new_x = x + dx[i];
int new_y = y + dy[i];
if (isValid(new_x, new_y)) {
visited[new_x][new_y] = true;
q.push(Node(new_x, new_y, 0));
}
}
}
return false;
}
int main() {
while (cin >> M >> N && M != 0 && N != 0) {
// 初始化迷宫和访问矩阵
for (int i = 1; i <= M; i++) {
for (int j = 1; j <= N; j++) {
cin >> maze[i][j];
visited[i][j] = false;
}
}
int start_x = 1, start_y = 1;
int end_x = M, end_y = N;
// 使用栈找最短路径
if (findShortestPath(start_x, start_y, end_x, end_y)) {
cout << endl;
} else {
// 使用队列找最短路径
if (findShortestPathBFS(start_x, start_y, end_x, end_y)) {
cout << endl;
} else {
cout << "没有通路" << endl;
}
}
}
return 0;
}
代码说明
findShortestPath()函数使用栈来实现深度优先搜索,它会优先探索当前节点的下一个方向,直到找到终点节点或所有节点都被访问过。findShortestPathBFS()函数使用队列来实现广度优先搜索,它会按照层级顺序探索所有节点,保证找到的最短路径。printPath()函数用于输出从终点到起点的路径,该路径是根据访问顺序反推得到的。
示例运行
例如,对于以下迷宫地图:
5 5
1 1 1 1 1
1 0 0 0 1
1 1 1 0 1
1 0 0 1 1
1 1 1 1 1
使用栈和队列找到的最短路径分别为:
- 使用栈找到的路径: (5,5,0),(5,4,4),(4,4,3),(4,3,3),(3,3,1),(2,3,1),(1,3,1),(1,2,2),(1,1,0)
- 使用队列找到的路径: (1,1,0),(2,1,2),(2,2,2),(3,2,2),(3,3,3),(4,3,3),(4,4,4),(5,4,4),(5,5,0)
总结
本文介绍了使用 C++ 实现迷宫求解算法,并使用栈和队列两种数据结构来寻找最短路径。该算法代码清晰易懂,可扩展性强,可以用于解决各种迷宫求解问题。
原文地址: https://www.cveoy.top/t/topic/XUX 著作权归作者所有。请勿转载和采集!