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以及虚拟化技术的书籍时还碰到了不少 ...
随机推荐
- ACM Doing Homework again
Ignatius刚刚从第30届ACM / ICPC回到学校.现在他有很多作业要做.每个老师给他一个截止作业的截止日期.如果Ignatius在截止日期之后进行了家庭作业,老师将减少他的最终考试成绩.现在 ...
- GDAL C#版本 "安全透明方法"问题解决方案
之前写过一篇关于再C#中调用GDAL库出现OSGeo.GDAL.GdalPINVOKE"的类型初始值设定项引发异常的解决方案,博客地址见下: http://blog.csdn.net/lim ...
- Maven 核心原理
Maven 核心原理 标签 : Java基础 Maven 是每一位Java工程师每天都会接触的工具, 但据我所知其实很多人对Maven理解的并不深, 只把它当做一个依赖管理工具(下载依赖.打包), M ...
- Rxjava +Retrofit 你需要掌握的几个技巧,Retrofit缓存,RxJava封装,统一对有无网络处理,异常处理, 返回结果问题
本文出处 :Tamic 文/ http://blog.csdn.net/sk719887916/article/details/52132106 Rxjava +Rterofit 需要掌握的几个技巧 ...
- norflash芯片内执行(XIP)
为什么程序不能直接在nandflash上执行?出于这个疑惑带来了这篇博文,是我在网上找了很多资料后总结的,假如有误,希望马上指出来,免得我误人子弟.谢谢! nandflash和norflash NOR ...
- Leetcode解题-链表(2.2.6)RotateList
1 题目:Rotate List Given a list, rotate the list to the right by k places, where k is non-negative. Fo ...
- String放入运行时常量池的时机与String.intern()方法解惑
运行时常量池概述 Java运行时常量池中主要存放两大类常量:字面量和符号引用.字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为final的常量值等. 而符号引用则属于编译原理方面的概念 ...
- 十六进制字符串转化为十进制值strtoul函数
eg: NSString *strtest =@"7fffffff"; NSUInteger val = strtoul([[strtest substringWithRange: ...
- Swift中如何转换不同类型的Mutable指针
在Swift中我们拥有强大高级逻辑抽象能力的同时,低级底层操作被刻意的限制了.但是有些情况下我们仍然想做一些在C语言中的hack工作,下面本猫就带大家看一看如何做这样的事. hacking is ha ...
- git中status指令总是提示内容被修改的解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近在用git提交项目修改时发现一个问题,就是多次 git a ...