DFS迷宫递归所有路径 新手入门
这篇文章写给自己以后复习和个个入门朋友:提示同学们一定耐心看完解释 哪怕看得很难受,我是新手我懂大家的心烦。看完后慢慢体会代码
我们假设迷宫为如下状况:
{0,0,1,0}
{0,0,1,0}
{0,0,0,0}
{0,0,1,0},
1为墙无法通行 只可以上下左右四个方向走动;目的:从左上角到右下角
DFS深度优先搜索算法思想:这里百度百科有很多 我这里推荐一个http://rapheal.iteye.com/blog/1526863;稍微看一下就好。由于是别人所以尊重原创所以我就不复制了。
那么用DFS解迷宫所有路径:我们在这里采用递归。我们从左上角当成“当前点”开始把出发坐标压入一个栈。每当入栈一个坐标 就把 迷宫所在所标的数值改为-1(当然1也可以,个人这样觉得比较好因为还可以复原迷宫);从左上角开始后从 左上角四个方向(上右下左)开始判断能否走通。比如我们判断当前点上方点的值是否为0;如果是0才可行走。如果上方可以走那么把此点当成当前点。继续判断“当前点”的四个方向,注意上一个当前点不赋值为-1 你就发现那么又要走回去了,因为上一个“当前点”是他左右上下其中的一个嘛。发生死递归等
比如java提示" java.lang.StackOverflowError。可能刚学的不知道什么意思,那么我们就先记住 “防止重复遍历此点”。
那么配图解释:
以上代表一个迷宫,每一格代表每一个通道。
绿色:墙
白色:可以走的路径;
蓝色:上一个当前点(本质是白色方便新手理解);
红色:当前点;(本质是白色)
解释:假如走到红色的地方 此时我们又要判断红色的左右上下可以走否。我们发现红色右是绿色 (墙相当于迷宫的1嘛)。左手边是白色(因为表示上一个当前点所以变成蓝色)所以你将走回去。你走过来走回去干嘛?下面不是还有路吗?所以你要记得把所有走过的节点设置为绿色(设置为1);
最后我们一个个遍历当遇到一个点无法通过时或者找到终点的话返回上一个递归(如果是找到结果,记得先输出逆序栈的坐标,就是其中一个迷宫出路) 返回后记得出栈、并把当前节点设置回0;原因“走不通返回上一个路口嘛。至于为什么重新设置回0的原因比较难阐述 :‘另一个路径又经过这里去寻找终点,却发现这条被走过就放弃从这里出发(其实没走过,是上一个路径走的),在这里有些人有人再想 【你说的和上面那么死递归不是冲突吗?】 其实这里没有冲突:假设我们当前点位B我们上一个当前点为''C(位于C的上方)’、 那么当前点为B
,假设B点除了C方向都是不能通行,而C又是被走过的节点。所以原路返回到到C(出栈一次) 并且B赋值为0; 回到C后我们继续检测其他方向(除了C方向也就是上),这样就不会再去判断上方,因为上下左右只会走一次走过上方发现走不通 就不会在去上了,所以B的值是0又怎么样? ”
代码:
import java.awt.Point;
import java.util.Stack; public class Main { //迷宫我们用二维数组表示,
//至于为什么边缘都是1,是我加上去的 这样你就可以防止边界越界。
//慢慢看后面的代码就知道了
public static int maze[][]={
//0 1 2 3 4 5
{1,1,1,1,1,1},//0
{1,0,0,1,0,1},//1
{1,0,0,1,0,1},//2
{1,0,0,0,0,1},//3
{1,0,0,1,0,1},//4
{1,1,1,1,1,1},//5
};
//四个方向嘛 上右下左(时针顺序)比如第一个item第一个坐标(-1,0)
//我们要计算当前点上面坐标 就加上 item第一个坐标值
//假设我们计算(X,Y) 上方坐标 那么就是(X+(-1),Y+0)左右下同理
static Point item [] ={new Point(-1,0),new Point(0,1),new Point(1,0),new Point(0,-1)};
//迷宫实际 行数和列数
static int row=4;
static int colum=4;
//用来保存坐标的栈
static public Stack<Point> stack =new Stack<Point>();
public static void main(String[] args) {
// TODO Auto-generated method stub DFS(row,colum,new Point(1,1)); } //参数信息row colum实际的迷宫总行数和列数 这两个固定的
//参数信息point当前节点
public static void DFS(int row,int colum,Point point){
//我们到左下角为终点 起点为左上角
maze[point.x][point.y]=-1;//走过当前节点所以赋值为-1
stack.add(point);
// System.out.println("入栈"+point);
int x,y;
x= point.x;
y= point.y;
//如果是最后结果
if(row==point.x && colum==point.y){
printPath();
//给最后一个节点赋值回0 不然别的路径怎么走得到?
maze[point.x][point.y]=0; }else{
//4个方向分别测试,比如从当前节点向上走不到终点那么返回
//那么在向右走
for (int i = 0; i < item.length; i++) {
Point temp =new Point(x+item[i].x,y+item[i].y);
if(maze[x+item[i].x][y+item[i].y]==0){
//如果当前方向可以走,那么进去下一个方向
DFS(Main.row,Main.colum,temp);
} }
} stack.pop();//出栈
maze[point.x][point.y]=0;
// System.out.println("出栈"+point);
}
//逆序输出栈里面的东西
public static void printPath(){ System.out.println("-----------------------");
for (Point point : Main.stack) {
System.out.print("["+point.x+","+point.y+"]");
}
System.out.println("-----------------------");
} }
最后再附上一个非递归版:
DFS迷宫递归所有路径 新手入门的更多相关文章
- 基于JavaFX图形界面演示的迷宫创建与路径寻找
事情的起因是收到了一位网友的请求,他的java课设需要设计实现迷宫相关的程序--如标题概括. 我这边不方便透露相关信息,就只把任务要求写出来. 演示视频指路: 视频过审后就更新链接 完整代码链接: 网 ...
- Linux 新手入门教程
Linux 新手入门教程 1991年10月5日,Linus Torvalds 在互联网上发布消息,宣布他自己开发的内核系统诞生了.他将内核源代码保存在芬兰最大的 FTP 网站上,命名为 Linux,取 ...
- Flume NG Getting Started(Flume NG 新手入门指南)
Flume NG Getting Started(Flume NG 新手入门指南)翻译 新手入门 Flume NG是什么? 有什么改变? 获得Flume NG 从源码构建 配置 flume-ng全局选 ...
- 原创:从零开始,微信小程序新手入门宝典《一》
为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习:一:微信小程序的特点张小龙:张小龙全面阐述小程序,推荐通读此文: 小程序是一种不需要下载.安装即可使用的 ...
- 课程上线 -“新手入门 : Windows Phone 8.1 开发”
经过近1个月的准备和录制,“新手入门 : Windows Phone 8.1 开发”系列课程已经在Microsoft 虚拟学院上线,链接地址为:http://www.microsoftvirtuala ...
- iOS简易柱状图(带动画)--新手入门篇
叨逼叨 好久没更新博客了,才几个月,发生了好多事情,处理了好多事情.不变的是写代码依然在继续. 做点啥子 看看objective-c的书,学着写了个柱状图,只是练习的demo而已,iOS上的图表控件已 ...
- Spring boot 1.3.5 RELEASE 官方文档中文翻译--Part2:新手入门
Part II. 新手入门 如果你刚刚开始学习Spring boot或"普通"的Spring,这部分非常适合你!在这里,我们回答了最基础的"什么是?".&quo ...
- PHP常用代码大全(新手入门必备)
PHP常用代码大全(新手入门必备),都是一些开发中常用的基础.需要的朋友可以参考下. 1.连接MYSQL数据库代码 <?php $connec=mysql_connect("loc ...
- Docker新手入门:基本用法
Docker新手入门:基本用法 1.Docker简介 1.1 第一本Docker书 工作中不断碰到Docker,今天终于算是正式开始学习了.在挑选系统学习Docker以及虚拟化技术的书籍时还碰到了不少 ...
随机推荐
- seaborn使用(样式管理)
seaborn使用(样式管理) Seaborn是一个在Python中制作具有吸引力和丰富信息的统计图形的库.它建立在matplotlib之上,并与PyData堆栈紧密集成,包括支持scipy和pand ...
- Java中Semaphore(信号量)的使用
Semaphore的作用: 在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了 ...
- GDAL C#版本 "安全透明方法"问题解决方案
之前写过一篇关于再C#中调用GDAL库出现OSGeo.GDAL.GdalPINVOKE"的类型初始值设定项引发异常的解决方案,博客地址见下: http://blog.csdn.net/lim ...
- ListView常见的优化方式简述
ListView的优化 对于ListView来说,应该算是布局中几种最常用的组件之一了,使用也十分方便,下面个大家介绍一下两种常见的优化方式. 1.条目复用优化 其实listview的工作原理就是,l ...
- 好IT男不能“淫”-谈IT人员目前普遍存在的“A情绪”
<如果当道德无法约束你的时候...那么就让对疾病的恐惧来制约你吧> 前言 在写这篇文章前我的心情无比的沉重.几次提笔欲写,几次又未能完成,可是最终让我"奋笔疾书"的原因 ...
- Programming In Scala笔记-第六章、函数式对象
这一章主要是以定义和完善一个有理数类Rational为线索,分析和介绍有关类定义,构造函数,方法重写,变量定义和私有化,以及对操作符的定义等. 一.Rational类定义和构造函数 1.定义一个空类 ...
- 【Android应用开发】 Universal Image Loader ( 使用简介 | 示例代码解析 )
作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/50824912 相关地址介绍 : -- Universal I ...
- JBOSS EAP 6 系列六 公共模块的jar配置到jboss的modules详细配置
公司项目中遇到并要解决的问题 1:原则上除了自己写的代码之外,公共的jar不应该都在打包的时候打包到ear里面,这样的话包太大,也不符合的分层的逻辑,在jboss容器内部,每个ear的包重复jar都会 ...
- android listview 使用
今天在做项目的时候用了自定义listview以及自定义的item.adapter.现在把其中需要注意的地方记录下来: 1.item内如果有button等控件时,在监听listview的onitemcl ...
- 【DevOps敏捷开发动手实验】开源文档 v2015.2 stable 版发布
Team Foundation Server 2015 Update 2版本终于在2周前的//Build 2016大会上正式发布了,借这个东风,小编也完成了[DevOps敏捷开发动手实验]开源文档的第 ...