使用递归方式写的走迷宫算法(Java)
2015-08-08 12:24
344 查看
[code]这段时间在补Java基础,是有点感觉。昨天老师给了个算法题,要求写一个走迷宫的算法出来。我之前可以说从未写过什么算法,一直都只是在机械地码代码,确实,这种码农没太大价值。是该写写算法提升一下自己了。 然后这个算法我没有参考过任何资料,也没看过任何其他人写好的代码,完完全全是自己摸索出来的。当时一整个下午都不知道该如何入手,勉强写了一个也走不出去,脑袋一片混乱。然后就搁置了。到了晚上11点过后打算重写,不过这个时候我惊奇地发现自己的思维无比的清晰,只花了一个小时左右就走出去了,不过这个算法肯定不是最忧算法,它仅仅只是走出了这个迷宫而已,甚至没有做最优路径处理,但也先这样了。刚开始练算法,要求不需要太高。 整体思路是这样的:创建一个ArrayDeque栈来保存老鼠走过的路径坐标。程序启动即找出老鼠的坐标。以该坐标点为初始值检测上、下、左、右四个方向是否有通道,当然,在检测前还必须先判断当前坐标点的四向坐标是否有效,即是否越界,通过一个`boolean isLocCor(int x,int y)`方法来判断。若在上方检测到有通路,即将当前的坐标入栈,将当前坐标标为已走过路段(以字符'@'表示),将上方坐标入栈,并以上方坐标为新坐标值进行检测,即递归此search(int x,int y)方法。若在上方没有检测到可通行的路,即将记录变量failCount自加1.若在上方检测到出口'e',即将当前坐标标为已走过路段,并将boolean标志finish置为true,结束当前方法。完成寻路。当四个方向都没有检测到可通行的路时,此时的failCount变量的值应为4,此时会将当前坐标标志为“死路”状态(以'n')表示,并将当前栈顶的元素弹出。 以此规则递归,最终即能得出正确的路径来。 当然,再次声明,本算法仅仅是实现了找到出路的功能而已,没有做其它优化。
[code]package maze; import java.util.ArrayDeque; public class MazeTest { /* * 使用递归求出路径。 * */ /*迷宫1 * private char[][] maze = new char[][]{ {'1','1','1','1','1','1','1','1','1','1','1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, 0, '1'}, {'1', 0, '1', 0, '1','1','1', 0, '1', 0, '1'}, {'e', 0, '1', 0, 0, 0, 0, 0, '1', 0, '1'}, {'1', 0, '1','1','1','1','1', 0, '1', 0, '1'}, {'1', 0, '1', 0, '1', 0, 0, 0, '1','1','1'}, {'1', 0, 0, 0, '1', 0, '1','1','1', 0, '1'}, {'1','1','1','1','1', 0, '1', 0, 0, 0, '1'}, {'1', 0, '1','m','1', 0, '1',0, 0, 0, '1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, 0, '1'}, {'1','1','1','1','1','1','1','1','1','1','1'}, };*/ /* * 迷宫2 private char[][] maze = new char[][]{ {'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, 0, '1'}, {'1', 0, '1', 0, 0, 0, '1', 0, '1', 0, '1'}, {'e', 0, '1', 0, 0, 0, 0, 0, '1', 0, '1'}, {'1', 0, '1', '1', '1', '1', '1', 0, '1', 0, '1'}, {'1', 0, '1', 0, '1', 0, 0, 0, '1', 0, '1'}, {'1', 0, 0, 0, '1', 0, '1', 0, 0, 0, '1'}, {'1', '1', '1', '1', '1', 0, '1', 0, 0, 0, '1'}, {'1', 0, '1', 'm', '1', 0, '1', 0, 0, 0, '1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, 0, '1'}, {'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'}, }; * / /* * 迷宫3 * * */ private char[][] maze = new char[][]{ {'1','1','1','1','1','1','1','1','1','1','1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, 0, '1'}, {'1', 0, '1', 0, '1','1','1', 0, '1', 0, '1'}, {'e', 0, '1', 0, 0, 0, 0, 0, '1', 0, '1'}, {'1', 0, '1','1','1','1','1', 0, '1', 0, '1'}, {'1', 0, '1', 0, '1', 0, 0, 0, '1', 0,'1'}, {'1', 0, 0, 0, '1', 0, '1', 0,'1', 0, '1'}, {'1','1','1','1','1', 0, '1', 0, '1',0, '1'}, {'1', 0, '1','1','1', 0, '1',0,'1', 0, '1'}, {'1', 0, 0, 0, 0, 0, '1', 0, 0, '1', '1'}, {'1','1','1','1','1','1','1','1',0,'m','1'}, }; private char pass = '@'; private char noPass = 'n'; private boolean finish = false; //定义一个用于存储老鼠走过的路径的栈集合。 ArrayDeque<MouseLoc> aDeque = new ArrayDeque<>(); //定义一个用于保存老鼠位置的类。 MouseLoc mLoc = new MouseLoc(); public static void main(String[] args) { // TODO Auto-generated method stub MazeTest mt = new MazeTest(); mt.init(); } void init(){ //打印出初始状态。 printMaze(); //找到老鼠当前位置。 this.findMouse(); System.out.println("老鼠的初始位置为:(" + mLoc.x + "," + mLoc.y + ")"); //把老鼠的初始位置加入到栈中。 aDeque.offerFirst(mLoc); //开始搜寻出路(递归)。 search(mLoc.x,mLoc.y); //寻路完毕,整理老鼠的路径。 for(int i=0;i<maze.length;i++) { for(int j=0;j<maze[i].length;j++) { if(maze[i][j] == noPass){ maze[i][j] = 0; } } } System.out.println("寻路结果为:\n"); printMaze(); System.out.println("老鼠走过的路径为:"); short stackSize = (short)aDeque.size(); for(short i=0;i<stackSize;i++){ MouseLoc ml = aDeque.removeLast(); System.out.println((1+i)+"、("+ml.x+","+ml.y+")"); } }// init method -- end. void search(int x,int y){ int failCount = 0; // 上 if(isLocCorr(x-1,y)){ if (!finish && maze[x-1][y] == 0) { /* * 如果检测到上方路段为可走空间,则去走,并 * 将此此空间标记为已走过路段。 * */ aDeque.offerFirst(new MouseLoc(x - 1, y)); // step1. push into stack. maze[x][y] = pass;//step2. sign it. search(x-1,y);// step3. new search. if(maze[x-1][y] == noPass){ failCount++; } } else if (maze[x - 1][y] == 'e') { /* * 如果检测到它是一个出口,则把当前位置标为已走过。 * 然后再把出口位置入栈,最后把出口位置标为已走过。 * 完成寻路。 * */ maze[x][y] = pass; aDeque.offerFirst(new MouseLoc(x-1,y)); maze[x - 1][y] = pass; finish = true; return; }else{ failCount++; } }else{ //如果位置检测不通过,也得让failCount的值自加1. failCount++; } // 下 if(isLocCorr(x+1, y)){ if (!finish && maze[x + 1][y] == 0) { aDeque.offerFirst(new MouseLoc(x + 1,y)); maze[x][y] = pass; search(x+1,y); if(maze[x+1][y] == noPass){ failCount++; } } else if (maze[x + 1][y] == 'e') { maze[x][y] = pass; aDeque.offerFirst(new MouseLoc(x-1,y)); maze[x+1][y] = pass; finish = true; return; }else{ failCount++; } }else{ //如果位置检测不通过,也得让failCount的值自加1. failCount++; } // 左 if(isLocCorr(x, y-1)){ if (!finish && maze[x][y - 1] == 0) { aDeque.offerFirst(new MouseLoc(x, y - 1)); maze[x][y] = pass; search(x,y-1); if(maze[x][y-1] == noPass){ failCount++; } } else if (maze[x][y - 1] == 'e') { maze[x][y] = pass; aDeque.offerFirst(new MouseLoc(x,y-1)); maze[x][y-1] = pass; finish = true; return; }else{ failCount++; } }else{ //如果位置检测不通过,也得让failCount的值自加1. failCount++; } // 右 if(isLocCorr(x, y+1)){ if (!finish && maze[x][y + 1] == 0) { aDeque.offerFirst(new MouseLoc(x, y + 1)); maze[x][y] = pass; search(x,y+1); if(maze[x][y+1] == noPass){ failCount++; } } else if (maze[x][y + 1] == 'e') { maze[x][y] = pass; aDeque.offerFirst(new MouseLoc(x,y+1)); maze[x][y+1] = pass; finish = true; return; }else{ failCount++; } }else{ //如果位置检测不通过,也得让failCount的值自加1. failCount++; } if(failCount == 4){ MouseLoc m = aDeque.pop(); maze[m.x][m.y] = noPass; } }// search method -- end. void printMaze(){ //专门打印迷宫阵列。 for(int i=0;i<maze.length;i++) { for(int j=0;j<maze[i].length;j++) { System.out.print(maze[i][j]); } System.out.println(""); } } private boolean isLocCorr(int x,int y){ //用于判断给定的位置坐标是否超出迷宫范围。 if(x<0 || y<0 || x>findYLength()-1 || y>findXLength()-1){ return false; } return true; } private int findYLength() { //返回迷宫上下距离。(y) return maze.length; } private int findXLength() { //返回迷宫左右距离。(x) return maze[0].length; } void findMouse(){ //用于寻找老鼠的起始位置。 for(int i=0;i<maze.length;i++) { for(int j=0;j<maze[i].length;j++) { if(maze[i][j] == 'm'){ mLoc.x = i; mLoc.y = j; return; } } } }// findMouse method -- end. }
以下是用于保存路径坐标的类。
[code]package maze; public class MouseLoc { public int x; public int y; MouseLoc(){ } MouseLoc(int x,int y){ this.x = x; this.y = y; } }
相关文章推荐
- Java_逃逸分析技术
- Spring Boot和JPA开发的一些坑
- struts & 运行机制
- Java并发编程之ConcurrentHashMap原理分析
- Spring3 MVC 深入研究
- Defining a controller with @Controller
- [笔记][Java7并发编程实战手册]2.2使用syncronized实现同步方法
- 配置struts2不当错误
- java 去掉html标签
- Setting property 'source' to 'org.eclipse.jst.jee.server:jeecg' did not find a matching property
- Implementing Controllers
- JAVA实现EXCEL公式专题(一)——EXCEL公式分类与解析步骤
- java怎么用一行代码初始化ArrayList
- java项目导出为一个可执行文件jar包
- java中j=J++综合理解
- java反射获取注解并拼接sql语句
- org.springframework.validation.BindException
- 解决Spring框架下中文乱码的问题
- Java Socket NIO详解(转)
- java容器类---Vector