迷宫寻路

本文介绍了BFS(广度优先搜索)算法如何用于解决迷宫寻路问题,通过队列数据结构和while循环实现一层一层的遍历以找到最短路径。在算法中,起点被放入队列,然后不断取出节点并检查是否为终点,直到找到终点。通过跟踪节点的路径,可以输出最短路径字符串。文章提供了具体的迷宫实例和详细步骤解析,并分享了作者的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迷宫寻路之BFS最短路径算法

写博客记录一下,还望大神指点。

  • BFS又叫广度优先搜索算法,就是利用队列这个数据结构与while循环,以发散搜索的方式一层一层的去遍历整个图。这个一层一层比较重要,因为刚好是这个东西能让我们找到迷宫的最短路径。
  • BFS的基本思路就是:
  • 初始化队列,将起始节点放入队尾
  • While(队列不为空)
    –取出队头节点Node
    –弹出队头节点Node
    –判断当前节点是否为终点
    -----处理该节点Node
    –把当前节点的相邻节点加入队尾

那么我们是怎么找到最短路径的呢?

  • 先利用这个伪代码求一下下面这个迷宫的最短路径长度:
    1 1 1 1 1 1 1
    1 0 0 0 0 0 1
    1 0 1 1 1 0 1
    1 0 0 0 1 0 1
    1 0 1 0 1 0 1
    1 1 0 0 0 0 1
    1 1 1 1 1 1 1
    其中第二行加粗的是起点,第六行的是终点。
    1.访问(1,1)这个点,这是第一层,不是终点,把相邻节点入队。
    2.访问(2,1)这个点,这是第二层,不是终点,把相邻节点入队。
    3.访问(1,2)这个点,这是第二层,不是终点,把相邻节点入队。
    3.访问(3,1)这个点,这是第三层,不是终点,把相邻节点入队。

    .访问(5,2)这个点,这是第八层,是终点,退出循环。

从这个过程中我们可以发现每次都会把相邻节点放到队尾,那么我们访问的时候就会先把同一层的访问完了,再访问下一层。而且,每一层与起点的距离就是层数减一,那么当找到终点时只需要输出这个层数减一,就得到了我们的最短路径长度。

现在要求的是最短路径(字符串)怎么办?
从上面的过程中我们发现,层数可以当成距离,那么可不可以给访问的的每一个节点再增加一个string类型的字符串,用来存储从起点到当前点的路径来解决这个问题呢。完全可以,只需要在每次入队的时候把当前这一步是怎么走的加入到这个字符串里,最后找到终点时,直接输出这个字符串就是要求的迷宫最短路径。

以下是我的代码:

#include <iostream>
#include <vector>
#include <queue>
#include <string>
#define STARTX 1//起点
#define STARTY 1
#define OVERX 5//终点
#define OVERY 2
using namespace std;
int maze[7][7] = {	1, 1, 1, 1, 1, 1, 1,
					1, 0, 0, 0, 0, 0, 1,
					1, 0, 1, 1, 1, 0, 1,
					1, 0, 0, 0, 1, 0, 1,
					1, 0, 1, 0, 1, 0, 1,
					1, 1, 0, 0, 0, 0, 1,
					1, 1, 1, 1, 1, 1, 1 };
struct Point {
	int x, y;
	string path;//存储路径
};
char dir[4] = { 'U','L','D','R' };
queue<Point> mazeQueue;
void BFSFindRoad();
int main() {
	BFSFindRoad();
	system("pause");
	return 0;
}

/**
*节点入队并标记
*/
void pushPoint2Queue(int x, int y, string path) {
	Point temp;
	temp.x = x; temp.y = y; temp.path = path;
	mazeQueue.push(temp);
	maze[x][y] = 1;
}

void BFSFindRoad() {
	Point temp;
	//初始化队列
	pushPoint2Queue(STARTX, STARTY,"");
	while (!mazeQueue.empty()) {
		temp = mazeQueue.front();
		mazeQueue.pop();
		if (temp.x == OVERX&&temp.y == OVERY) {
			cout << "最短路径:"<< temp.path << endl;
			return;
		}
		//邻接节点入队并添加路径
		if (maze[temp.x - 1][temp.y] == 0) pushPoint2Queue(temp.x - 1, temp.y, temp.path + dir[0]);
		if (maze[temp.x][temp.y - 1] == 0) pushPoint2Queue(temp.x, temp.y - 1, temp.path + dir[1]);
		if (maze[temp.x + 1][temp.y] == 0) pushPoint2Queue(temp.x + 1, temp.y, temp.path + dir[2]);
		if (maze[temp.x][temp.y + 1] == 0) pushPoint2Queue(temp.x, temp.y + 1, temp.path + dir[3]);
	}
	cout << "没发现路径" << endl;
}

我就是在存储路径的时候做了改进,不使用另外的一个数组来保存每一个点的前驱节点,直接使用路径变量保存路径。同时只有队列里的元素才会保存路径,避免了回溯输出路径的问题。书上那个也不叫回溯,只不过我觉得比较像回溯,因为它里面每个变量存了上一个节点的坐标,然后又通过这个坐标去找上上个坐标,还是比较像回溯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值