迷宫问题-DFS-BFS

这篇具有很好参考价值的文章主要介绍了迷宫问题-DFS-BFS。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

迷宫问题简介

🚀学习过算法程序设计的应该都学习过迷宫这个问题,迷宫问题主要设计的算法就是DFS-深度优先遍历和BFS-广度优先遍历。
🚀在一个二维数组中,元素为1的位置表示这个位置是墙,0表示有通路,迷宫的入口和出口都是0(否则不会有路径能出去),并且路径不唯一。例如下图:

迷宫问题-DFS-BFS

🚀图中这个迷宫有两条路径,分别用粉色和蓝色标记了出来,明显粉色路径的长度是比蓝色路径要短的。

BFS解决迷宫最短路径问题

🚀BFS可以解决最短路径的原因是,BFS是像水波一样逐渐向外圈波及的,很明显最先波及到的通路就是最短路径。

🚀使用BFS算法的思想

一般的广度优先遍历都是采用队列完成的,每次取对头然后将其周围四个位置压到队列当中,然后pop掉对头,这样循环下去直到队列为空就停止。但是这种算法无法记录迷宫走过的路径,所以我才用vector来模拟队列来使用,就相当于对头的数据不pop掉,而是用一个下标来控制,现在走到哪个下标了,并且存储当前位置的结构体中多设置了一个变量prev,存储的是这个位置的上个位置在vector中的下标。这样在迷宫中走到终点的时候,返回这个vector,里面就有我们过的路径了。

🚀代码实现

struct path
{
	int _x;
	int _y;
	int _prev; // 在模拟对列中的下标位置
	path(int x,int y,int prev)
		:_x(x)
		,_y(y)
		,_prev(prev)
	{}
};
bool check(int i, int j, int map[][8], int row, int col)
{
	if (i < 0 || j < 0 || i > row - 1 || j > col - 1)
		return false;
	if (map[i][j] == -1) //走过的位置被设置为-1
		return false;
	if (map[i][j] == 1)
		return false;
	return true;
}

vector<path> BFS(int map[][8], int row, int col)
{
	vector<path> v;
	v.push_back(path(0, 0, -1));
	size_t index = 0;
	int fx[4] = { 0,1,-1,0 };
	int fy[4] = { 1,0,0,-1 };
	int i = 0, j = 0;//当前位置的横纵坐标
	while (index < v.size())
	{
		i = v[index]._x;
		j = v[index]._y;
		for (int k = 0; k < 4; k++)
		{
			int new_i = i + fx[k];
			int new_j = j + fy[k];
			if (check(new_i, new_j, map, row, col))
			{
				v.push_back(path(new_i, new_j, index));
				map[new_i][new_j] = -1;
				if (new_i == row - 1 && new_j == col - 1)
					return v;
			}
		}
		index++;
	}
	cout << "error" << endl;
	return v;
}
int main()
{
	int map[7][8] = {
		{0,0,0,1,1,1,1,1},
		{0,1,0,1,1,1,1,1},
		{0,1,0,1,0,0,0,1},
		{0,1,0,1,0,1,0,1},
		{0,1,0,0,0,1,0,1},
		{0,1,1,1,1,1,0,1},
		{0,0,0,0,0,0,0,0}
	};
	vector<path> res = BFS(map, 7, 8);
	int i = res.size() - 1;
	while (i >= 0)
	{
		cout << "(" << res[i]._x << "," << res[i]._y << ")" << endl;
		i = res[i]._prev;
	}
}

🚀运行结果
迷宫问题-DFS-BFS
🚀你会发现打印的结果是从终点走向起点的,我们可以对其做一下修改。使用递归的方式逆向打印出结果。

void Print(vector<path>& v, int index)
{
	if (index == 0)
	{
		cout << "(" << v[index]._x << "," << v[index]._y << ")" << endl;
		return;
	}
	Print(v, v[index]._prev);
	cout << "(" << v[index]._x << "," << v[index]._y << ")" << endl;
}

🚀这样我们就能得到正向的路径了。
迷宫问题-DFS-BFS

DFS记录迷宫路径

🚀BFS算法思想

深度优先搜索是,一条道走到黑,走不通再换另一条路,对于深度优先搜索,我们可以用栈来记录它的路径,每次进入程序后,先将当前位置压栈,再让他向上下左右去试探,值得注意的是要在最后进行弹栈处理,因为如果上下左右都我没有返回true表明从此位置出发是到不了终点的,说明此位置不在最终的路径当中,所以要弹栈。并且在开始的时候将此位置压栈后,要将此位置对应的数据改为-1,表明在后面的递归中不能往回走了(会造成死循环),并且在弹栈后要将此位置的值修改为0,这是因为这层函数栈帧已经结束,返回到上一层栈帧中,而返回到上一层栈帧的时候,这个位置是没有被访问的。

🚀代码实现

bool DFS(int map[][8], int row, int col, stack<_path>& st,int i,int j)
{
	st.push(_path(i, j));
	map[i][j] = -1;
	if (i == row - 1 && j == col - 1)
		return true;
	if (check(i + 1, j, map, row, col))
		if (DFS(map, row, col, st, i + 1, j))
			return true;
	if (check(i, j + 1, map, row, col)) 
		if (DFS(map, row, col, st, i, j + 1))
			return true;
	if (check(i - 1, j, map, row, col))
		if (DFS(map, row, col, st, i - 1, j))
			return true;
	if (check(i, j - 1, map, row, col))
		if (DFS(map, row, col, st, i, j - 1))
			return true;
	map[i][j] = 0;
	st.pop();
	return false;
}

int main()
{
	int map[7][8] = {
		{0,0,0,1,1,1,1,1},
		{0,1,0,1,1,1,1,1},
		{0,1,0,1,0,0,0,1},
		{0,1,0,1,0,1,0,1},
		{0,1,0,0,0,1,0,1},
		{0,1,1,1,1,1,0,1},
		{0,0,0,0,0,0,0,0}
	};
	//vector<path> res = BFS(map, 7, 8);
	//int i = res.size() - 1;
	/*while (i >= 0)
	{
		cout << "(" << res[i]._x << "," << res[i]._y << ")" << endl;
		i = res[i]._prev;
	}*/
	//Print(res, i);
	stack<_path> st;
	DFS(map, 7, 8, st, 0, 0);
	while (!st.empty())
	{
		cout << "(" << st.top()._x << "," << st.top()._y << ")" << endl;
		st.pop();
	}
}

🚀运行结果
迷宫问题-DFS-BFS

可以返现这个路径仍然是从终点到起点的,所以如果想要正序输出那么仍然要做修正。
但是还要注意的是,迷宫中有两条路径,栈中只记录了一条路径,恰巧这个路径是最短路径,注意这是恰巧,这和你第一步的走向有关。如果你改变走向结果也可能会变,所以DFS并不适合求最短路径,但是用来求路径还是没毛病的。

bool DFS(int map[][8], int row, int col, stack<_path>& st,int i,int j)
{
	st.push(_path(i, j));
	map[i][j] = -1;
	if (i == row - 1 && j == col - 1)
		return true;
	if (check(i, j + 1, map, row, col)) //先向右走
		if (DFS(map, row, col, st, i, j + 1))
			return true;
	if (check(i + 1, j, map, row, col))
		if (DFS(map, row, col, st, i + 1, j))
			return true;
	if (check(i - 1, j, map, row, col))
		if (DFS(map, row, col, st, i - 1, j))
			return true;
	if (check(i, j - 1, map, row, col))
		if (DFS(map, row, col, st, i, j - 1))
			return true;
	map[i][j] = 0;
	st.pop();
	return false;
}

迷宫问题-DFS-BFS
🚀可以看到先向右走的时候,栈中存储的数据就是另一条路径了,这也验证了DFS不适合求最短路径。注意我说的是不适合不代表DFS不能求最短路径。

DFS解决迷宫所有路径问题

🚀思路

求所有路径,我们可以使用vector,每一步都记录在vector中,如果当前位置到达了终点,那么就打印vector中的路径。

🚀代码

void DFS2(int map[][8], int row, int col, int i, int j, vector<_path> v)
{
	v.push_back(_path(i, j));
	map[i][j] = -1;
	if (i == row - 1 && j == col - 1)
	{
		for (int i = 0; i < v.size(); i++)
		{
			cout << "(" << v[i]._x << "," << v[i]._y << ")" << endl;
		}
		cout << "-------------------------------" << endl;
	}
	if (check(i, j + 1, map, row, col)) //先向右走
		DFS2(map, row, col, i, j + 1,v);
	if (check(i + 1, j, map, row, col))
		DFS2(map, row, col,  i + 1, j, v);
	if (check(i - 1, j, map, row, col))
		DFS2(map, row, col,  i - 1, j,v);
	if (check(i, j - 1, map, row, col))
		DFS2(map, row, col,  i, j - 1,v);
	map[i][j] = 0;
}

🚀结果展示
迷宫问题-DFS-BFS文章来源地址https://www.toymoban.com/news/detail-421746.html

到了这里,关于迷宫问题-DFS-BFS的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图论岛屿问题DFS+BFS

    leetcode 200 岛屿问题 BFS代码

    2024年02月09日
    浏览(37)
  • 迷宫DFS问题(二维vector, pair,模板题)

    HJ43 迷宫问题

    2024年02月12日
    浏览(35)
  • 【数据结构】迷宫问题DFS非递归(c语言实现)

    本来之前写过一个推箱子,就想着写个迷宫游戏,因为想着推箱子游戏里面也有墙,也有玩家的移动,比推箱子简单的是还不用判断前面是否有箱子的情况,但是自己写的迷宫游戏如果自己随机生成的迷宫地图的话,不一定会有通路,他要学一个什么随机迷宫的生成,刚看完

    2024年02月08日
    浏览(39)
  • 【算法详解 | DFS算法】深度优先搜索解走迷宫问题 | 深度优先图遍历

    by.Qin3Yu 本文需要读者掌握 结构体 和 栈 的操作基础,完整代码将在文章末尾展示。 特别声明:本文为了尽可能使用简单描述,以求简单明了,可能部分专有名词定义不准确。 栈相关操作可以参考我的往期博文: 【C++数据结构 | 栈速通】使用栈完成十进制数转二四八进制数

    2024年02月03日
    浏览(51)
  • BFS4专题 迷宫最短路径(输出路径)

    输入 输出         这里刚开始看的时候会可能有点复杂了,因为是递归。 但是只要理解了含义,脑袋里模拟一下还是可以理解的。首先还是 之前那样 BFS 常规搜索 只是这里不用输出步数了,所以我们可以省略一层循环,直接搜索求路径。 求路径的方法核心思想就是 记录每

    2024年02月11日
    浏览(39)
  • 迷宫的最少步数and最短路径(BFS)

    题目描述 一个迷宫由 R 行 C 列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。 输入 第一行是两个整数,R 和 C ,代表迷宫的

    2024年02月14日
    浏览(37)
  • 1432 - 走出迷宫的最少步数-广度优先搜索BFS

    代码

    2024年01月20日
    浏览(83)
  • DFS算法详解 ---- 走迷宫

    上期内容给大家带来了排列型dfs,这期给大家带来了 使用dfs来进行图的遍历 。 首先请看题: 咱们在看这道题的时候 ,需要首先研究 迷宫如何存 ,肯定是要定义一个浮点型的二维数组对吧,那么这里我给他定义一个char board[N][N],让这个二维数组存储迷宫。 接下来就是 怎么

    2024年01月16日
    浏览(40)
  • 图论:DFS与BFS

    目录 1.DFS(图论) 1.1.DFS过程 1.2.应用 2.BFS(图论) 2.1.BFS过程 2.2.应用 2.3.双端队列BFS 实现 2.4.优先队列BFS(堆优化 Dijkstra算法) DFS全称是,中文名是深度优先搜索,是一种用于遍历或搜索树或图的算法。所谓深度优先,就是说每次都尝试向更深的节点走。广义上的DFS:DFS最

    2024年03月24日
    浏览(32)
  • 拓扑排序算法 -- dfs、bfs

    210. 课程表 II 该题用到「拓扑排序」的算法思想,关于拓扑排序,直观地说就是,让你把⼀幅图「拉平」,⽽且这个「拉平」的图⾥⾯,所有箭头⽅向都是⼀致的,⽐如上图所有箭头都是朝右的。 很显然,如果⼀幅有向图中存在环,是⽆法进⾏拓扑排序的,因为肯定做不到所

    2024年02月10日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包