java 递归_采用递归算法求解迷宫问题(Java版) | 附代码+视频

b6774cb61381192ab0c525506f90e6d8.png

递归算法能够解决很多计算机科学问题,迷宫问题就是其中一个典型案例。本篇教程我们将采用递归算法求解迷宫问题,输出从入口到出口的所有迷宫路径。

26d3fb9d5ddc9144056fc70a32314652.png

01

用递归算法解决迷宫问题

迷宫问题在《数据结构教程》第3章介绍过,设mgpath(int xi,int yi,int xe,int ye,path)是求从(xi,yi)到(xe,ye)的迷宫路径,用path变量保存一条迷宫路径,它是元素为Box类型的ArrayList对象,其中Box类定义如下:

class Box                                        //方块类
{    int i;                                      //方块的行号int j;                                      //方块的列号public Box(int i1,int j1)      //构造方法{   i=i1;j=j1;}
}

当从(xi,yi)方块找到一个相邻可走方块(i,j)后,mgpath(i,j,xe,ye,path)表示求从(i,j)到出口(xe,ye)的迷宫路径。显然,mgpath(xi,yi,xe,ye,path)是“大问题”,而mgpath(i,j,xe,ye,path)是“小问题”(即大问题=试探一步+小问题),如下图所示。

3e79fc645e33a2ad15c9c7e044eb9c86.png

▍大小问题的关系

求解上述迷宫问题的递归模型如下:

mgpath(xi,yi,xe,ye,path)将(xi,yi)添加到path中;                    若(xi,yi)=(xe,ye)即找到出口
置mg[xi][yi]=-1;
输出path中的迷宫路径;
恢复出口迷宫值为0即置mg[xe][ye]=0
mgpath(xi,yi,xe,ye,path)将(xi,yi)添加到path中;                        若(xi,yi)不是出口
置mg[xi][yi]=-1;
对于(xi,yi)每个相邻可走方块(i,j),调用mg(i,j,xe,ye,path);
path回退一步并置mg[xi][yi]=0;

上述递归模型中,对于方块(xi,yi),先添加到path末尾(所有path中的方块都是通道,所以初始调用时入口必须是通道),对于它的每一个相邻可走方块(i,j)都执行“小问题”mgpath(i,j,xe,ye,path),之后需要从(xi,yi)方块回退(删除path中的末尾方块)并置mg[xi][yi]为0,其目的是恢复前面求迷宫路径而改变的环境,以便找出所有的迷宫路径。以下图的迷宫为例:

8a2a889624cd07928f6172cc18101c2f.png

▍迷宫示意图

求入口(1,1)到出口(4,4)所有迷宫路径的完整程序如下:

import java.lang.*;
import java.util.*;
class Box                                            //方块类
{    int i;                                          //方块的行号
    int j;                                          //方块的列号
    public Box(int i1,int j1)                           //构造方法{   i=i1;j=j1;}
}
class MazeClass                                    //求解迷宫路径类
{    final int MaxSize=20;
    int [][] mg;                                        //迷宫数组
    int m,n;                                            //迷宫行列数
    int cnt=0;                                      //累计迷宫路径数
    public MazeClass(int m1,int n1)                 //构造方法{   m=m1;
        n=n1;
        mg=new int[MaxSize][MaxSize];
    }
    public void Setmg(int [][] a)                       //设置迷宫数组{   for (int i=0;i            for (int j=0;j                mg[i][j]=a[i][j];
    }
    void mgpath(int xi,intyi,intxe,intye,ArrayList path)  //求解迷宫路径为:(xi,yi)->(xe,ye){   Box b;
        int di,i=0,j=0;
        b=new Box(xi,yi);
        path.add(b);                                    //将(xi,yi)添加到path中
        mg[xi][yi]=-1;                              //mg[xi][yi]=-1     
        if (xi==xe&&yi==ye)                     //找到了出口,输出一个迷宫路径
        {   System.out.printf("迷宫路径%d:",++cnt); //输出path中的迷宫路径
            for (int k=0;k                System.out.printf("  (%d,%d)",path.get(k).i,path.get(k).j);
            System.out.println();
            mg[xi][yi]=0;                           //恢复为0,否则别的路径找不到出口
        }
        else                                            //(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;
                }
                if (mg[i][j]==0)                        //(i,j)可走时
                    mgpath(i,j,xe,ye,path);         //从(i,j)出发查找迷宫路径
                di++;                               //继续处理(xi,yi)下一个相邻方块
            }
        }
        path.remove(path.size()-1);                 //删除path末尾方格(回退一个方块)
        mg[xi][yi]=0;
    }
}
public class Exam5_5
{    public static void main(String[] args){   int [][] a= { {1,1,1,1,1,1},{1,0,1,0,0,1},
                {1,0,0,1,1,1},{1,0,1,0,0,1},
                {1,0,0,0,0,1},{1,1,1,1,1,1} };
        MazeClassmz=new MazeClass(6,6);
        ArrayList path=new ArrayList();
        mz.Setmg(a);
        mz.mgpath(1,1,4,4,path);
    }
}

上述程序的执行结果如下:

迷宫路径1: (1,1)  (2,1)  (3,1)  (4,1)  (4,2)  (4,3)  (3,3)  (3,4)  (4,4)
迷宫路径2: (1,1)  (2,1)  (3,1)  (4,1)  (4,2)  (4,3)  (4,4)

本例算法求出所有的迷宫路径,可以通过路径长度比较求出最短迷宫路径(可能存在多条最短迷宫路径)。

02

视频讲解

视频教程如下:

03

源代码下载

关注微信公众号,后台回复关键词“迷宫问题”即可获得完整源代码。

【参考书籍】

《数据结构教程(Java语言描述)》

ISBN:978-7-302-55134-8

李春葆 编著

定价:69.8元

2f987780a9dd43c7d182406e6f49625d.png

f82bf0c8416410965f0891f147c70c72.png

上一篇:

用Python写一个智力问答游戏 | 附代码+视频

利用神经网络实现股票预测 | 附代码

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

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

相关文章

挂机宝装mysql_挂机宝安装

万安挂机宝下载后安装包里有介绍.proxydroid使用说明以雷电模拟器为例永久记住选择 允许 (安卓手机 需要 root 方可使用)设置 账号密码启动即可 下面是详细翻译说明一、下载ProxyDroid。二、对ProxyDroid进行配置(基本配置&#xff1a;)(1) Auto Setting不勾选&#xff0c;我们…

python爬虫是数据挖掘吗_爬虫属于数据挖掘 python为什么叫爬虫

数据挖掘和爬虫有区别吗&#xff1f;数据挖掘和爬虫有很大的区别。数据挖掘过程应用于爬虫的可能性并不是特别大&#xff0c;但所占比例相对较大。但是使用爬虫&#xff0c;一般来说&#xff0c;爬虫都是爬到别人的网站上的&#xff0c;而且有些规则。因此&#xff0c;从数据挖…

通过代理上网 固定ip_浅析局部代理IP与全局代理IP的使用说明

经常有人问&#xff0c;如何设置局部代理IP&#xff0c;如何设置全局代理IP&#xff0c;今天我们一起来看看。何谓局部代理IP&#xff0c;顾名思义&#xff0c;改变局部的IP&#xff0c;不影响其他程序软件运行的使用IP&#xff1b;所谓全局代理IP&#xff0c;就是改变整个客户…

如何检查私钥和公钥是否配对_如何检查家具是否有臭虫

如果您购买了二手家具&#xff0c;或者家具使用好多年了&#xff0c;那么由于家庭环境等问题&#xff0c;难免会出现臭虫&#xff01;臭虫可以通过许多不同的方式进入您的房屋&#xff0c;但是最常见的方法之一是您的二手家具。关于臭虫首先&#xff0c;让我们从臭虫入门。这些…

利用expect安装mysql_linux使用mysqldump+expect+crontab实现mysql周期冷备份思路详解

一、遇到的问题我们使用过mysqldump都知道&#xff0c;使用该命令后&#xff0c;需要我们手动输入 mysql的密码&#xff0c;那么我们就不能够直接在crontab中使用mysqldump实现周期备份。其实我们可以使用expect脚本自动输入密码&#xff0c;从而实现真正的周期备份。如果你不知…

数据结构实验之图论九:最小生成树_初高中数学竞赛训练----图论初步2

例题中有2019年罗马尼亚大师赛第3试题树树&#xff1a;一个连通图&#xff0c;如果没有一个环&#xff0c;则叫树。森林&#xff1a;若干个独立的树形成一个森林。链&#xff1a;一个特殊的树是节点中&#xff0c;除去两个节点的度为1&#xff0c;其它均为2&#xff0c;叫做链。…

在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式

Spring Data JPA的运行原理&#xff1a;PersistenceContext(name"entityManagerFactory") private EntityManager em; Test public void test1(){ //org.springframework.data.jpa.repository.support.SimpleJpaRepositor yfba8bf //System.out.println(this.u…

467python教程_Magnus Lie Hetland的《Python基础教程(第3版)》自学笔记(持续更新中)...

转载请注明原创出处&#xff0c;谢谢&#xff01;如果读完觉得有收获的话&#xff0c;欢迎点赞加关注。Python基础教程.jpg快速上手&#xff1a;基础知识交互式解释器在Python交互式解释器的提示符>>>后面输入help()可以获取指南&#xff0c;在IDLE中&#xff0c;还可…

java 获取所有带指定注解的类名_SXT DAY023 反射和注解

1. 反射机制介绍_Class对象获取反射机制是 Java 的动态性之一 动态语言:在程序运行时&#xff0c;可以改变程序的结构或变量的 类型。反射机制的常见作用动态的加载类、动态的获取类的信息(属性&#xff0c;方法&#xff0c;构造 器) 动态构造对象 动态调用类和对象的任意方法、…

tomcat勾连mysql_tomcat9.0启动脚本startup.bat的分析

1、 Apache Tomcat的下载和安装从Apache官网https://tomcat.apache.org/可以下载各种版本的tomcat软件&#xff0c;下载的文件格式可以是zip/tar.gz/exe形式的。如下图所示&#xff0c;在64位windows中使用tomcat&#xff0c;我们可以下载"64-bit Windows.zip",直接解…

安卓能硬改的手机机型_【每日新闻】小米11部分镜头参数爆料;华为重新采购手机零部件 重启4G手机生产...

数据铸造影响力关注每日行业热点资讯&#xff0c;掌握业界动态趋势&#xff0c;以下是今天的精彩内容&#xff1a;1、小米11部分镜头参数爆料&#xff1a;超大底50MP主摄&#xff0c;长焦达12MP或48MP2、华为重新采购手机零部件 重启4G手机生产1、小米11部分镜头参数爆料&#…

kafka集群为什么需要三个节点_大白话带你认识 Kafka

前言应大部分的小伙伴的要求&#xff0c;在Yarn之前先来一个kafka的小插曲&#xff0c;轻松愉快。一、Kafka基础消息系统的作用应该大部份小伙伴都清楚&#xff0c;用机油装箱举个例子所以消息系统就是如上图我们所说的仓库&#xff0c;能在中间过程作为缓存&#xff0c;并且实…

mysql对日期的操作_MySql对日期的操作

1、计算俩个日期之间所差的天数select datediff(2018-09-18,2018-09-01)2、计算日期是这周的星期几select dayofweek(2018-09-18)1.因为外国一般都是把星期天认为是一周的开始&#xff0c;所以用这种方法一般都得减去一天才是这周的星期几select date_format(2018-09-17,"…

sql移动加权计算利润_计算机视觉中的半监督学习

作者&#xff1a;Amit Chaudhary编译&#xff1a;ronghuaiyang导读图解半监督的各种方法的关键思想。计算机视觉的半监督学习方法在过去几年得到了快速发展。目前最先进的方法是在结构和损失函数方面对之前的工作进行了简化&#xff0c;以及引入了通过混合不同方案的混合方法。…

.net 启动mysql数据库连接_[ASP.net教程]mysql数据库连接方式(.net)

[ASP.net教程]mysql数据库连接方式(.net)0 2014-07-17 18:01:001.通过ado.net连接(数据库连接串中为中文貌似无法使用)需要添加MySql.Data.dll(可通过安装mysql-connector-net-6.8.3.mis获得)引用MySql.Data.dll调用方式string connectionString “serverlocalhost;port3306;da…

overflowhidden把内容遮住了怎么办_图片有水印怎么办?不用PS,有这4招就够了!...

图片是我们在做 PPT 时经常会使用到的高频元素。往往会在搜索引擎中搜到很多带有水印的图片&#xff0c;怎么办呢&#xff1f;固然 PS 等软件去水印很给力&#xff0c;但是对于连 PPT 都还没有用得很熟悉的同学&#xff0c;让他们再去下载安装 Photoshop 软件&#xff0c;仅仅只…

mysql开窗函数over_oracle分析函数技术详解(配上开窗函数over())

一、Oracle分析函数入门 分析函数是什么&#xff1f; 分析函数是Oracle专门用于 解决复杂报表统计需求 的功能强大的函数&#xff0c; 它可以在数据中进行分组然后计算基于组的某种统计 &#xff0c;并且每一组的每一行都可以返回一个统计。 分析函数和聚合函数的不同之处是什么…

传递给系统调用的数据区域太小怎么解决_一口气说出“分布式追踪系统”原理!...

“ 在微服务架构中&#xff0c;一次请求往往涉及到多个模块&#xff0c;多个中间件&#xff0c;多台机器的相互协作才能完成。图片来自 Pexels这一系列调用请求中&#xff0c;有些是串行的&#xff0c;有些是并行的&#xff0c;那么如何确定这个请求背后调用了哪些应用&#xf…

语义分割和实例分割_一文读懂语义分割与实例分割

以人工智能为导向的现代计算机视觉技术&#xff0c;在过去的十年中发生了巨大的变化。今天&#xff0c;它被广泛用于图像分类、人脸识别、物体检测、视频分析以及机器人及自动驾驶汽车中的图像处理等领域。图像分割技术是目前预测图像领域最热门的一项技术&#xff0c;原因在于…

游戏自审自查报告_开发的射箭小游戏上线了,分享一下我在开发过程中遇到的问题...

利用业余时间开发的微信小游戏-射箭救人质上线了&#xff0c;主要玩法就是操作弓箭射断绳子把人救下来就可以了。图片资源是我找一个朋友做的。开发过程不算太顺利。磕磕绊绊做了12关。希望大家支持下。谢谢。分享一下我在开发中遇到的问题和部分解决方案、希望对大家有所帮助。…