[C/C++] -- DFS搜索迷宫路径

news2024/12/23 14:41:35

设计一个程序,能够对给定的迷宫进行路径搜索,并输出一条从起点到终点的路径。具体来说,程序需要实现以下功能:

  1. 接受用户输入的迷宫地图,包括迷宫的行数和列数,以及每个格子的状态(0 表示可通行,1 表示不可通行)。
  2. 使用深度优先搜索算法(DFS)对迷宫进行搜索,找到从起点到终点的一条路径。
  3. 输出搜索到的路径。

入栈以后,然后我们查看栈顶元素,是(0,0)这个节点。栈现在不为空,取栈顶元素,先看它右边能不能走,能走的话,就一直向右走,它右边是0,就入栈了。

_pMaze[0][0]._val == 1
    return;
_stack. Push(_pMaze[0][0]);//左上角节点入栈 
while (!_stack. Empty())//栈不为空 
	Node top = _stack. Top();

 如果栈顶元素的右边可以走的话,我们要把当前节点的右方向改成不能走,把右边节点的左方向改成不能走。因为不能走回头路,而且因为路子走不通回退后也不能继续走相同的死路。

//往右方向寻找
			if (_pMaze[x][y]._state[RIGHT] == YES)
			{
				_pMaze[x][y]._state[RIGHT] = NO;
				_pMaze[x][y + 1]._state[LEFT] = NO;
				_stack.push(_pMaze[x][y + 1]);
				continue;

深度遍历入栈后,不用判断之前节点的方向。continue后,重新取栈顶元素,继续进行判断。同理,如果右边不能走,下边可以走的话:

//往下方向寻找
			if (_pMaze[x][y]._state[DOWN] == YES)
			{
				_pMaze[x][y]._state[DOWN] = NO;
				_pMaze[x + 1][y]._state[UP] = NO;
				_stack.push(_pMaze[x + 1][y]);
				continue;
			}

 同理:左方向

//往左方向寻找
			if (_pMaze[x][y]._state[LEFT] == YES)
			{
				_pMaze[x][y]._state[LEFT] = NO;
				_pMaze[x][y - 1]._state[RIGHT] = NO;
				_stack.push(_pMaze[x][y - 1]);
				continue;
			}

如果栈顶元素判断完四个方向都不能走,就是到死路了,就把栈顶元素出栈。
然后再取栈顶元素,进行判断,如果它的4个方向都不能走,就出栈,如果栈为空,则迷宫无通路。如果有方向能走,就继续走下去。以此类推下去。但是,都要判断一下此节点是不是右下角的节点,如果是,就是找到通路了。

//已经找到右下角出口得迷宫路径
			if (x == _row - 1 && y == _col - 1)
			{
				return;
			}

 完整代码:

#include <iostream>
#include <stack>
using namespace std;

//定义迷宫每一个节点的四个方向
const int RIGHT = 0;//右 
const int DOWN = 1;//下 
const int LEFT = 2;//左 
const int UP = 3;//上 

//迷宫每一个节点方向的数量
const int WAY_NUM = 4;

//定义节点行走状态
const int YES = 4;//当前方向可以走 
const int NO = 5;//当前方向不能走 

//迷宫
class Maze
{
public:
	//初始化迷宫,根据用户输入的行列数,生成存储迷宫路径信息的二维数组
	Maze(int row, int col)
		:_row(row)
		, _col(col)
	{
		_pMaze = new Node*[_row];//注意元素类型是Node 
		for (int i = 0; i < _row; ++i)
		{
			_pMaze[i] = new Node[_col];
		}
	}

	//初始化迷宫路径节点信息
	void initNode(int x, int y, int val)
	{
		_pMaze[x][y]._x = x;
		_pMaze[x][y]._y = y;
		_pMaze[x][y]._val = val;
		//节点四个方向默认的初始化都为不能走 
		for (int i = 0; i < WAY_NUM; ++i)
		{
			_pMaze[x][y]._state[i] = NO;
		}
	}

	//初始化迷宫0节点四个方向的行走状态信息 当前节点右下左上,如果是0,改成可以走 
	void setNodeState()
	{
		for (int i = 0; i < _row; ++i)
		{
			for (int j = 0; j < _col; ++j)
			{
				if (_pMaze[i][j]._val == 1)
				{
					continue;//不用调整了,因为走不到值为1的节点 
				}
				
                //j不能取到最后一列,不然就判断越界了 
				if (j < _col - 1 && _pMaze[i][j + 1]._val == 0)
				//逻辑&,是先计算左边的表达式,左边如果是false,右边就不用计算了 
				{
					_pMaze[i][j]._state[RIGHT] = YES;
				}

				if (i < _row - 1 && _pMaze[i + 1][j]._val == 0)
				{
					_pMaze[i][j]._state[DOWN] = YES;
				}
				
                //j不用取第一类,因为本身就不能走 
				if (j > 0 && _pMaze[i][j - 1]._val == 0)
				{
					_pMaze[i][j]._state[LEFT] = YES;
				}

				if (i > 0 && _pMaze[i - 1][j]._val == 0)
				{
					_pMaze[i][j]._state[UP] = YES;
				}
			}
		}
	}

	//深度搜索迷宫路径
	void searchMazePath()
	{
		if (_pMaze[0][0]._val == 1)
		{
			return;
		}
		_stack.push(_pMaze[0][0]);//左上角节点入栈 

		while (!_stack.empty())//栈不为空 
		{
			Node top = _stack.top();
			int x = top._x;
			int y = top._y;

			//已经找到右下角出口得迷宫路径
			if (x == _row - 1 && y == _col - 1)
			{
				return;
			}

			//往右方向寻找
			if (_pMaze[x][y]._state[RIGHT] == YES)
			{
				_pMaze[x][y]._state[RIGHT] = NO;
				_pMaze[x][y + 1]._state[LEFT] = NO;
				_stack.push(_pMaze[x][y + 1]);
				continue;
			}

			//往下方向寻找
			if (_pMaze[x][y]._state[DOWN] == YES)
			{
				_pMaze[x][y]._state[DOWN] = NO;
				_pMaze[x + 1][y]._state[UP] = NO;
				_stack.push(_pMaze[x + 1][y]);
				continue;
			}

			//往左方向寻找
			if (_pMaze[x][y]._state[LEFT] == YES)
			{
				_pMaze[x][y]._state[LEFT] = NO;
				_pMaze[x][y - 1]._state[RIGHT] = NO;
				_stack.push(_pMaze[x][y - 1]);
				continue;
			}

			//往上方向寻找
			if (_pMaze[x][y]._state[UP] == YES)
			{
				_pMaze[x][y]._state[UP] = NO;
				_pMaze[x - 1][y]._state[DOWN] = NO;
				_stack.push(_pMaze[x - 1][y]);
				continue;
			}

			_stack.pop();
		}
	}

	//打印迷宫路径搜索结果
	void showMazePath()
	{
		if (_stack.empty())
		{
			cout << "不存在一条迷宫路径!" << endl;
		}
		else
		{
			while (!_stack.empty())//栈不为空,取出节点坐标,相应值调整为* 
			{
				Node top = _stack.top();
				_pMaze[top._x][top._y]._val = '*';
				_stack.pop();
			}

			for (int i = 0; i < _row; ++i)//打印迷宫
			{
				for (int j = 0; j < _col; ++j)
				{
					if (_pMaze[i][j]._val == '*')
					{
						cout << "* ";
					}
					else
					{
						cout << _pMaze[i][j]._val << " ";
					}
				}
				cout << endl;
			}
		}
	}
private:
	//定义迷宫节点路径信息
	struct Node
	{
		int _x;//节点的横坐标 
		int _y;//节点的纵坐标 
		int _val;//节点的值
		int _state[WAY_NUM];//记录节点四个方向的状态(左右上下)
		//4个元素位置(左右上下),存储yes或者no 
	};

	Node **_pMaze;//动态生成迷宫路径(动态开辟二维数组) 
	int _row;//迷宫的行 
	int _col;//迷宫的列 
	stack<Node> _stack;//栈结构,辅助深度搜索迷宫路径
};

int main()
{
	cout << "请输入迷宫的行列数(例如:10 10):";
	int row, col, data;
	cin >> row >> col;

	Maze maze(row, col);//创建迷宫对象

	cout << "请输入迷宫的路径信息(0表示可以走,1表示不能走):" << endl;
	for (int i = 0; i < row; ++i)//只能获取i,j和data值,节点的4个方向的行走状态还不能初始化 
	{
		for (int j = 0; j < col; ++j)
		{
			cin >> data;
			//可以初始化迷宫节点的基本信息
			maze.initNode(i, j, data);
		}
	}

	//开始设置所有节点的四个方向的状态
	maze.setNodeState();

	//开始从左上角搜索迷宫的路径信息了
	maze.searchMazePath();

	//打印迷宫路径搜索的结果
	maze.showMazePath();

	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1658623.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十四五”智慧城市:视频大数据汇聚系统2.0建设方案与特点分析

一、背景需求分析 随着科技的不断发展&#xff0c;智慧城市的建设已经成为城市发展的重要方向。视频汇聚系统作为智慧城市建设的重要组成部分&#xff0c;已经得到了广泛的应用和推广。视频汇聚系统是智慧城市中非常重要的组成部分&#xff0c;它利用摄像头和传感器技术来收集…

Python | Leetcode Python题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; class Solution:def removeDuplicates(self, nums: List[int]) -> int:idx, left, right 0, 0, 0while left < len(nums):nums[idx] nums[left]idx 1while right < len(nums) and nums[right] nums[left]:right 1if right - …

【深度学习】时空图卷积网络(STGCN),预测交通流量

论文地址&#xff1a;https://arxiv.org/abs/1709.04875 Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic Forecasting 文章目录 一、摘要二、数据集介绍美国洛杉矶交通数据集 METR-LA 介绍美国加利福尼亚交通数据集 PEMS-BAY 介绍美国…

ASP.NET校园新闻发布系统的设计与实现

摘 要 校园新闻发布系统是在学校区域内为学校教育提供资源共享、信息交流和协同工作的计算机网络信息系统。随着网络技术的发展和Internet应用的普及&#xff0c;互联网已成为人们获取信息的重要来源。由于现在各大学校的教师和学生对信息的需求越来越高&#xff0c;校园信息…

SQL优化详解

目录 插入数据 insert的优化&#xff08;少量数据&#xff09; 批量插入 手动事务提交 主键顺序插入 插入大量数据 主键优化 数据组织方式&#xff1a; 页分裂&#xff1a; 主键顺序插入的方式&#xff1a; 主键乱序插入&#xff1a; 页合并&#xff1a; 主键设计…

软件技术主要学什么课程

软件技术专业主要学习的课程和内容有编程语言、数据结构与算法、数据库技术等&#xff0c;以下是上大学网( www.sdaxue.com)整理的软件技术主要学什么课程&#xff0c;供大家参考&#xff01; 编程语言&#xff1a;掌握一种或多种编程语言&#xff0c;如C#、Java、Python、C等&…

EdgeOne 免费证书快速实现网站 HTTPS 访问

在当今互联网环境下&#xff0c;HTTPS访问已经成为现代网站的必备功能。HTTPS 访问不仅能够更有效地保障用户在访问到网站时的数据安全传输&#xff0c;防止信息泄露、消息劫持等问题&#xff0c;在搜索引擎中&#xff0c;未实现 HTTPS 还会被浏览器提示为不安全网站&#xff0…

Windows平台PyCharm之PySide6开发环境搭建与配置

PySide6 是一个用于创建跨平台 GUI 应用程序的库&#xff0c;它是 Qt for Python 的官方库。Qt 是一个跨平台的 C 应用程序框架&#xff0c;用于开发具有图形用户界面&#xff08;GUI&#xff09;的应用程序。PySide6 允许开发者使用 Python 语言访问 Qt 的功能&#xff0c;从而…

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2

ICode国际青少年编程竞赛- Python-2级训练场-综合练习2 1、 Flyer[0].step() Flyer[1].step() Dev.step(4)2、 for i in range(2):Flyer[i].step()Dev.step(2)Dev.turnLeft() Flyer[0].step(2) Dev.step(2)3、 for i in range(2):Flyer[i * 2 1].step()Dev.step(-i - 2)Dev.tu…

OpenAI 发布 AI 生成图片检测器;Meta 推出 AI 广告创意工具;Google 正式发布 Pixel 8a,主打 AI

OpenAI 发布 AI 生成图片检测器 OpenAI 昨日官宣推出专用的 AI 监测工具&#xff0c;用于监测图片是否由其旗下 AI 图片生成工具 DALL-E 生成&#xff0c;准确率高达 98.8%。 不过该公司表示&#xff0c;这个检测工具并非旨在检测 Midjourney 和 Stability 等其他流行生成器生…

QAnything 在mac M2 上纯python环境安装使用体验(避坑指南)

这是一篇mac m2本地纯python环境安装 qanything的文章。安装并不顺利&#xff0c;官方提供的模型无法在本地跑。 这篇文章记录了&#xff0c;使用xinference来部署本地模型&#xff0c;并利用openAi的通用接口的方式&#xff0c;可以正常使用。 记录了遇到的所有的问题&#xf…

使用Docker安装Nginx

一、Nginx介绍 Nginx 是一款高性能的开源 Web 服务器和反向代理服务器&#xff0c;具有高效能、高稳定性、低资源消耗等优点。可以处理大量并发请求&#xff0c;支持多种协议&#xff0c;还能实现负载均衡、缓存等功能&#xff0c;在互联网应用中被广泛使用。在Nginx中&#xf…

ICode国际青少年编程竞赛- Python-2级训练场-迷宫

ICode国际青少年编程竞赛- Python-2级训练场-迷宫 1、 Dev.step(3) Dev.turnLeft() for i in range(2):Dev.step(4)Dev.turnRight() for i in range(2):Dev.step(2)Dev.turnLeft() Dev.step(3) Dev.step(-9)2、 Dev.step(3) Dev.turnRight() Dev.step(2) Dev.turnLeft() for i …

AI视频教程下载:给企业管理层和商业精英的ChatGpt课程

课程内容大纲&#xff1a; 1-引言 2-面向初学者的生成性人工智能 3-与ChatGPT一起学习提示101 详细介绍了如何使用ChatGPT的六种沟通模式&#xff0c;并提供了各种实际应用场景和示例&#xff1a; **Q&A模式&#xff08;问题与答案模式&#xff09;**&#xff1a; - 这…

区块链 | NFT 水印:Review on Watermarking Techniques(三)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证&#xff0c;即通过使用 R S A \mathsf{RSA} RSA…

96、技巧-只出现一次的数字

思路 首先不考虑额外空间的话使用一个set去重即可。第二种就是异或运算。 异或操作的性质 身份元素&#xff1a;任何数与0进行异或运算&#xff0c;结果仍然是原数&#xff0c;即 x ^ 0 x。自反性&#xff1a;任何数与自身进行异或运算&#xff0c;结果是0&#xff0c;即 x…

Spring Cloud Consul 4.1.1

该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型习惯用法&#xff0c;为 Spring Boot 应用程序提供 Consul 集成。通过一些简单的注释&#xff0c;您可以快速启用和配置应用程序内的常见模式&#xff0c;并使用基于 Consul 的组件构建大型分布式系统。提供的模式…

Python版Spark core详解

文章目录 第一章 SparkCore1.1. Spark环境部署1.1.1. Spark介绍1.1.1.1. 什么是Spark1.1.1.2. Spark与MapReduce的对比框架对比运行流程对比 1.1.1.3. Spark的组件1.1.1.4. Spark的特点 1.1.2. Spark的安装部署1.1.2.1. Spark安装包下载1.1.2.2. Spark部署模式介绍1.1.2.3. Loc…

解决Vue devtools插件数据变化不会自动刷新

我们使用devtools插件在监测vuex中表单或自定义组件的数据&#xff0c;发现页面数据发生变化后&#xff0c;但是devtools中还是老数据&#xff0c;必须手动点击devtools刷新才能拿到最新的数据。很烦&#xff01; 解决方案&#xff1a; 打开chrome的设置&#xff0c;向下翻&…

docker自建GitLab仓库

摘要 GitLab 是一个功能强大的开源代码托管平台&#xff0c;它不仅提供了代码存储和版本控制的核心功能&#xff0c;还集成了项目管理、CI/CD 流水线、代码审查等企业级特性。本文将指导你如何在自己的服务器上搭建 GitLab 社区版&#xff0c;创建一个完全属于自己的开源仓库&…