洪水填充算法走迷宫
作者:野牛程序员:2024-08-26 12:05:05 C++阅读 2987
洪水填充算法走迷宫
使用洪水填充算法走迷宫是一种有效的方法,尤其是在解决迷宫中的“可达性”问题时。洪水填充算法可以用来标记迷宫中从起点出发可以到达的所有位置,最终找到从起点到终点的路径。
基本思路
起点:从迷宫的起点出发,开始填充。
相邻节点扩展:检查当前节点的相邻节点(上下左右),如果该节点是通道且未被访问过,则将其加入到队列中进行填充。
终点检查:在填充过程中,如果某个节点是终点,说明找到了从起点到终点的路径。
路径重构:可以通过回溯的方法从终点反向寻找起点,重构路径。
C++代码实现
下面的代码实现了一个简单的迷宫求解器,使用了广度优先搜索(BFS),这是洪水填充算法的一种应用。
#include <iostream> #include <queue> #include <vector> #include <stack> using namespace std; struct Point { int x, y; }; // 判断点是否在迷宫范围内,并且是否为通道 bool isValid(int x, int y, const vector<vector<int>>& maze, const vector<vector<bool>>& visited) { int rows = maze.size(); int cols = maze[0].size(); return (x >= 0 && x < rows && y >= 0 && y < cols && maze[x][y] == 0 && !visited[x][y]); } // 使用洪水填充算法走迷宫,找到从起点到终点的路径 bool floodFillMaze(vector<vector<int>>& maze, Point start, Point end) { int rows = maze.size(); int cols = maze[0].size(); // 方向数组,表示上下左右四个方向 int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 用于记录每个点是否被访问过 vector<vector<bool>> visited(rows, vector<bool>(cols, false)); // 用于记录路径的前一个点 vector<vector<Point>> prev(rows, vector<Point>(cols, {-1, -1})); queue<Point> q; q.push(start); visited[start.x][start.y] = true; while (!q.empty()) { Point current = q.front(); q.pop(); // 如果到达终点,开始重构路径 if (current.x == end.x && current.y == end.y) { stack<Point> path; while (current.x != start.x || current.y != start.y) { path.push(current); current = prev[current.x][current.y]; } path.push(start); cout << "Path from start to end:" << endl; while (!path.empty()) { Point p = path.top(); path.pop(); cout << "(" << p.x << ", " << p.y << ") "; } cout << endl; return true; } // 扩展到相邻的四个方向 for (auto& dir : directions) { int nx = current.x + dir[0]; int ny = current.y + dir[1]; if (isValid(nx, ny, maze, visited)) { q.push({nx, ny}); visited[nx][ny] = true; prev[nx][ny] = current; } } } cout << "No path found." << endl; return false; } int main() { vector<vector<int>> maze = { {0, 1, 0, 0, 0, 0}, {0, 1, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 0} }; Point start = {0, 0}; // 起点 Point end = {5, 5}; // 终点 floodFillMaze(maze, start, end); return 0; }
代码解释
结构体
Point
:用于表示迷宫中的一个点,包含
x
和y
坐标。函数
isValid
:检查给定的坐标是否在迷宫的有效范围内,并且是通道(值为0)且未被访问过。
函数
floodFillMaze
:使用广度优先搜索(BFS)来模拟洪水填充算法。
queue<Point>
用于存储当前正在处理的迷宫节点。visited
数组标记已经访问过的节点,防止重复访问。prev
数组记录每个节点的前一个节点,用于路径重构。路径重构:
当找到终点时,通过回溯
prev
数组从终点回到起点,重构并输出路径。主函数
main
:初始化一个迷宫,其中
0
表示通道,1
表示墙壁。指定起点和终点,调用
floodFillMaze
函数寻找路径。
输出示例
程序运行后,将输出从起点到终点的路径,如果存在的话。输出的路径是一系列从起点到终点的坐标序列。
注意
迷宫中的
0
表示通道,1
表示墙壁。程序找到的是一条可行路径,可能不是最短路径,但在BFS的情况下,通常是最短路径。
野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892