【详解】求解迷宫所有路径(递归实现)----直接打穿迷宫

news2025/1/11 22:53:38

目录

递归的模型:

栈帧:

递归调用深度:

​编辑

用递归算法求解迷宫问题:

小结:

结语:


递归的小小总结,朋友们可以看看,有助于理解后面的递归程序。

递归的模型:

递归模型由递归出口递归体两部分组成,递归出口即递归的结束条件,递归体确定递归求解时的递推关系。

这两步缺一不可,没出口会死循环,没有递归体求解不出答案。(建议大家做递归题时一定要在纸上把这两个写出来,递归代码实现不难,难的是思路

栈帧:

单个函数调用操作所使用的函数调用栈被称为栈帧结构简单来说就是每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。

递归调用深度:

类似于这样的递归调用深度为4,其实就是大问题化到递归出口需要调用递归函数的次数。

深度不能太大,会栈溢出。

用递归算法求解迷宫问题:

自定义PathType来存储每一步的数据

Box为每个点的数据类型

用count来存储一共有几条路可以走

大部分解析都在代码里面了,我这里就不多叙述。

typedef struct
{
	int i;				//当前方块的行号
	int j;				//当前方块的列号
} Box;
typedef struct
{
	Box data[MaxSize];
    int length;			//路径长度
} PathType;				//定义路径类型
int count=0;			//存放迷宫路径的条数

求解迷宫函数mgpath参数xi,yi为当前的坐标,xe,ye为迷宫出口的坐标,path用来保存每一步,一但找到出口就把path输出(path其实是顺序表结构),可能有的朋友不太懂为什么要回退,这是因为我们要找迷宫的所有出口,进行回溯,这样递归就能进行全部查找,和树差不多(由于这样的空间消耗很大,和时间复杂度较高,所以迷宫不适合太大)。

void mgpath(int xi,int yi,int xe,int ye,PathType path)
//求解路径为:(xi,yi)->(xe,ye)
{
	int di,k,i,j;
	if (xi==xe && yi==ye)		//找到了出口,输出路径
	{
		path.data[path.length].i = xi;
		path.data[path.length].j = yi;
		path.length++;
		printf("迷宫路径%d如下:\n",++count);
		for (k=0;k<path.length;k++)
			printf("\t(%d,%d)",path.data[k].i,path.data[k].j);
		printf("\n");
	}
	else						//(xi,yi)不是出口
	{
		if (mg[xi][yi]==0)		//(xi,yi)是一个可走方块
		{
			di=0;
			while (di<4)		//找(xi,yi)的一个相邻方块(i,j)
			{
				switch(di)
				{
				case 0:i=xi-1; j=yi;   break;
				case 1:i=xi;   j=yi+1; break;
				case 2:i=xi+1; j=yi;   break;
				case 3:i=xi;   j=yi-1; break;
				}
				path.data[path.length].i = xi;
				path.data[path.length].j = yi;
				path.length++;
				mg[xi][yi]=-1;			//避免重复找路径
				mgpath(i,j,xe,ye,path);
				path.length--;			//回退一个方块
				mg[xi][yi]=0;			//恢复(xi,yi)为可走
				di++;
			}
		}
	}
}

总代码:

#define  _CRT_SECURE_NO_WARNINGS 1
//【例5.5】的算法:递归算法求解从入口到出口的所有迷宫路径
#include <stdio.h>
#define MaxSize 100
#define M 4
#define N 4
int mg[M+2][N+2]={ {1,1,1,1,1,1},{1,0,0,0,1,1},{1,0,1,0,0,1},{1,0,0,0,1,1},{1,1,0,0,0,1},{1,1,1,1,1,1} };

typedef struct
{
	int i;				//当前方块的行号
	int j;				//当前方块的列号
} Box;
typedef struct
{
	Box data[MaxSize];
    int length;			//路径长度
} PathType;				//定义路径类型
int count=0;			//存放迷宫路径的条数
void mgpath(int xi,int yi,int xe,int ye,PathType path)
//求解路径为:(xi,yi)->(xe,ye)
{
	int di,k,i,j;
	if (xi==xe && yi==ye)		//找到了出口,输出路径
	{
		path.data[path.length].i = xi;
		path.data[path.length].j = yi;
		path.length++;
		printf("迷宫路径%d如下:\n",++count);
		for (k=0;k<path.length;k++)
			printf("\t(%d,%d)",path.data[k].i,path.data[k].j);
		printf("\n");
	}
	else						//(xi,yi)不是出口
	{
		if (mg[xi][yi]==0)		//(xi,yi)是一个可走方块
		{
			di=0;
			while (di<4)		//找(xi,yi)的一个相邻方块(i,j)
			{
				switch(di)
				{
				case 0:i=xi-1; j=yi;   break;
				case 1:i=xi;   j=yi+1; break;
				case 2:i=xi+1; j=yi;   break;
				case 3:i=xi;   j=yi-1; break;
				}
				path.data[path.length].i = xi;
				path.data[path.length].j = yi;
				path.length++;
				mg[xi][yi]=-1;			//避免重复找路径
				mgpath(i,j,xe,ye,path);
				path.length--;			//回退一个方块
				mg[xi][yi]=0;			//恢复(xi,yi)为可走
				di++;
			}
		}
	}
}
int main()
{
	PathType path;
	path.length=0;				//初始化路径长度
	mgpath(1,1,M,N,path);
	return 1;
}

小结:

递归问题一般都要先把解题思路想好,再进行解答,有时递归的深度比较大,可能要自己转换为递推形式,然后就相信函数,相信自己,有一些小细节不必深究(不然你可能就会陷入无穷的细节无法自拔)。

结语:

其实写博客不仅仅是为了教大家,同时这也有利于我巩固自己的知识点,和一个学习的总结,对文章有任何问题的还请指出,接受大家的批评,让我改进,如果大家有所收获的话还请不要吝啬你们的点赞和收藏,这可以激励我写出更加优秀的文章。

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

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

相关文章

钡铼技术2023年年度报告来了

不积跬步&#xff0c;无以至千里&#xff1b; 不积小流&#xff0c;无以成江海。 钡铼的2023年 平凡却又意义深远。 在工业自动化及物联网技术发展的道路上&#xff0c;钡铼技术每一个进步都源于不懈的努力和持续的积累。钡铼技术在过去的一年中&#xff0c;稳扎稳打&#xf…

QCharView使用

QChart是 QGraphicsWidget的子类。 QCharView是QGraphicsView的子类 QCharView概念:title、系列、图标Chart、视图 说明: 需要添加Qt组件charts 在使用QChart或者QChartView之前需要添加宏定义QT_CHARTS_USE_NAMESPACE &#xff08;其实是使用了命名空间&#xff09;&#xff…

前端uniapp的tab选项卡for循环切换、开通VIP实战案例【带源码/最新】

目录 效果图图1图2 源码最后 这个案例是uniapp&#xff0c;同样也适用Vue项目&#xff0c;语法一样for循环&#xff0c;点击切换 效果图 图1 图2 源码 直接代码复制查看效果 <template><view class"my-helper-service-pass"><view class"tab…

服务号怎么改为订阅号

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;很多小伙伴想把服务号改为订阅号&#xff0c;但是不知道改了之后具体有什么作用&#xff0c;今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章&#xff0c;但是订阅号每天都可以发…

Windows系统如何使用VNC远程连接Deepin桌面【内网穿透】

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 x11vnc是一种在Linux系统中实现远程桌面控制的工具&#xff0c;它的原理是通过X Window系统的协议来实现远程桌面的展…

L1-078:吉老师的回归

题目描述 曾经在天梯赛大杀四方的吉老师决定回归天梯赛赛场啦&#xff01; 为了简化题目&#xff0c;我们不妨假设天梯赛的每道题目可以用一个不超过 500 的、只包括可打印符号的字符串描述出来&#xff0c;如&#xff1a;Problem A: Print "Hello world!"。 众所周知…

jdbc源码研究

JDBC介绍 JDBC&#xff08;Java Data Base Connectivity,java数据库连接&#xff09;是一种用于执行SQL语句的Java API&#xff0c;可以为多种关系数据库提供统一访问&#xff0c;它由一组用Java语言编写的类和接口组成。 开发者不必为每家数据通信协议的不同而疲于奔命&#…

竞赛保研 基于深度学习的人脸专注度检测计算系统 - opencv python cnn

文章目录 1 前言2 相关技术2.1CNN简介2.2 人脸识别算法2.3专注检测原理2.4 OpenCV 3 功能介绍3.1人脸录入功能3.2 人脸识别3.3 人脸专注度检测3.4 识别记录 4 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的人脸专注度…

联合体类型和枚举类型

联合体 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫&#xff1a;共⽤体。 所以给联合体其中⼀个成员赋值&#xff0c;其他成员的值也跟着…

Android WiFi基础概览

Android WiFi 基础概览 1、WiFi协议2、Android WLAN 架构2.1 应用框架2.2 Wi-Fi 服务2.3 Wi-Fi HAL 3、相关编译 android13-release 1、WiFi协议 Wi-Fi&#xff08;无线通信技术&#xff09;_百度百科 2.4GHz 频段支持以下标准&#xff08;802.11b/g/n/ax&#xff09;&#xff…

web期末作业动态时钟UI界面毛玻璃版

效果图 html代码奉上 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthde…

【创作1024天纪念日】我的创作纪念日 【1024天 == 程序员节】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Http与Tcp协议的原理以及应用

OSI七层模型和相关协议 七层模型从上到下如下所示&#xff1a; 应用层&#xff1a;负责应用之间的通信&#xff0c;处理请求和响应的具体格式表示层&#xff1a;对于数据格式进行处理会话层&#xff1a;负责建立和断开通信连接&#xff0c;传输层&#xff1a;负责建立端口之间…

音量控制软件sound control mac功能亮点

sound control mac可以帮助用户控制某个独立应用程序的音量&#xff0c;通过每应用音量&#xff0c;均衡器&#xff0c;平衡和音频路由独立控制每个应用的音频&#xff0c;还有整个系统的音量。 sound control mac功能亮点 每个应用程序的音量控制 独立控制应用的数量。 键盘音…

UI5与后端的文件交互(一)

文章目录 前言一、RAP的开发1. 创建表格2. 创建CDS Entity3. 创建BDEF4. 创建implementation class5. 创建Service Definition和Binding6. 测试API 二、创建UI5 Project1. 使用Basic模板创建2. 创建View3. 测试页面及绑定的oData数据是否正确4. 创建Controller5. 导入外部包&am…

IP地址定位技术的应用及其重要性

随着网络技术的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;IP地址定位技术在网络安全领域的应用也越来越广泛。本文将介绍IP地址定位技术在网络安全领域的应用及其重要性。 一、IP地址定位技术概述 IP地址定位技术是指通过一定的技术手段&#xff0c;将虚拟网络中的…

这些软件测试面试题你都会,那offer还不手拿把掐

问&#xff1a;你在测试中发现了一个 bug &#xff0c;但是开发经理认为这不是一个 bug &#xff0c;你应该怎样解决。 首先&#xff0c;将问题提交到缺陷管理库里面进行备案然后&#xff0c;要获取判断的依据和标准&#xff1a;根据需求说明书、产品说明、设计文档等&#xf…

Git(2):Git环境的安装

本教程里的git命令例子都是在Git Bash中演示的&#xff0c;会用到一些基本的linux命令&#xff0c;在此为大家提前列举&#xff1a; ls/ll 查看当前目录cat 查看文件内容touch 创建文件vi vi编辑器&#xff08;使用vi编辑器是为了方便展示效果&#xff0c;学员可以记事本、edi…

一个H3C交换机周期性断网并自动恢复的排查案例

一个朋友发我一个H3C日志&#xff0c;这个交换机是汇聚层交换机&#xff0c;1和2口是trunk口&#xff0c;其它接口是access接口&#xff0c;17-21口据说接的都是监控、终端。日志里面看到大量的拓朴改变&#xff0c;好几个网口up、down的日志&#xff0c;怀疑是环路&#xff0c…

Pycharm打包程序为exe文件

Pycharm打包程序为exe文件 【一】导入模块pyinstaller 【1】图片说明 【2】文字说明 根据图片顺序执行 首先点击file进入settings界面&#xff0c;在setting界面找到Project下面的Python Interpretor&#xff0c;点击号进行模块的添加在搜索框中输入pyinstaller&#xff0c;…