java实现迷宫算法--转
沿着所有方向进行探测,有路径则走,没有路径则从栈中回退。
回溯法是一种不断试探且及时纠正错误的搜索方法,下面的求解过程采用回溯法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达一个新点,否则试探下一个方向;若所有的方向均没有通路,则沿原路返回前一点,换下一个方向继续试探,直到所有可能的通路都搜索到,或找到一条通路,或无路可走又返回到入口点。这里可以用一个栈来实现,每走一步,将该位置压入栈中,若该点无路可走,则出栈返回上一位置。
需要解决的四个问题:
(1)表示迷宫的数据结构
设迷宫为m行n列,利用数组maze[m][n]来表示一个迷宫,maze[i][j]=0或1,其中0表示通路,1表示不通。迷宫该数组四边都为1,代表迷宫四周都是墙。这样就可以保证每个点都有8个方向可以试探。
入口为(1,1),出口为(6,8)
1,1,1,1,1,1,1,1,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,1,0,1,1,1,1,1
1,0,1,0,0,0,0,0,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,0,1,1,0,0,0,1
1,0,1,1,0,0,1,1,0,1
1,1,1,1,1,1,1,1,1,1
(2)试探方向
迷宫中间每个点都有8个方向可以试探。其增量数组可以用一个8*2的二维数组move表述,表示对当前点而言,它周围8个点的行和列的坐标偏移量.具体值如下:
x y
0 1
1 1
1 0
1 -1
0 -1
-1 -1
-1 0
-1 1
在move数组中,x表示横坐标的增量,y表示纵坐标的增量。
(3)栈中存放元素的设计
栈中所存放的元素应该包含所到达的每点的坐标以及从该点沿哪个方向向下走的,可用一个类表示:
class Step{
int x,y,d;
public Step(int x,int y,int d) {
this.x = x;//横坐标
this.y = y;//纵坐标
this.d = d;//方向
}
}
(4)防止重复到达某点而发生死循环
使maze[i][j]置为-1,以便区别为达到的点,同样也可以防止走重复点的作用。
源码如下:
package com.test; import java.util.Stack;
class Step{
int x,y,d;
public Step(int x,int y,int d) {
this.x = x;//横坐标
this.y = y;//纵坐标
this.d = d;//方向
}
} public class MazeTest { public static void main(String[] args) {
// 迷宫定义
int[][] maze = {{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}};
int[][] move = {{,},{,},{,},{,-},{,-},{-,-},{-,},{-,}};
Stack s = new Stack();
Stack s1 = new Stack();
int a = path(maze, move, s);
while(!s.isEmpty()){
Step step = s.pop();
System.out.println(step.x+":"+step.y);
}
}
public static int path(int[][] maze,int[][] move,Stack s){
Step temp = new Step(,,-); //起点
s.push(temp);
while(!s.isEmpty()){
temp = s.pop();
int x = temp.x;
int y = temp.y;
int d = temp.d+;
while(d<){
int i = x + move[d][];
int j = y + move[d][];
if(maze[i][j] == ){ //该点可达
temp = new Step(i,j,d); //到达新点
s.push(temp);
x = i;
y = j;
maze[x][y] = -; //到达新点,标志已经到达
if(x == && y == ){
return ; //到达出口,迷宫有路,返回1
}else{
d = ; //重新初始化方向
}
}else{
d++; //改变方向
}
}
}
return ;
} }
代码2:
import java.util.*; class Position{
public Position(){ } public Position(int row, int col){
this.col = col;
this.row = row;
} public String toString(){
return "(" + row + " ," + col + ")";
} int row;
int col;
} class Maze{
public Maze(){
maze = new int[][];
stack = new Stack<Position>();
p = new boolean[][];
} /*
* 构造迷宫
*/
public void init(){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入迷宫的行数");
row = scanner.nextInt();
System.out.println("请输入迷宫的列数");
col = scanner.nextInt();
System.out.println("请输入" + row + "行" + col + "列的迷宫");
int temp = ;
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
temp = scanner.nextInt();
maze[i][j] = temp;
p[i][j] = false;
}
}
} /*
* 回溯迷宫,查看是否有出路
*/
public void findPath(){
// 给原始迷宫的周围家一圈围墙
int temp[][] = new int[row + ][col + ];
for(int i = ; i < row + ; ++i) {
for(int j = ; j < col + ; ++j) {
temp[][j] = ;
temp[row + ][j] = ;
temp[i][] = temp[i][col + ] = ;
}
}
// 将原始迷宫复制到新的迷宫中
for(int i = ; i < row; ++i) {
for(int j = ; j < col; ++j) {
temp[i + ][j + ] = maze[i][j];
}
}
// 从左上角开始按照顺时针开始查询 int i = ;
int j = ;
p[i][j] = true;
stack.push(new Position(i, j));
while (!stack.empty() && (!(i == (row) && (j == col)))) { if ((temp[i][j + ] == ) && (p[i][j + ] == false)) {
p[i][j + ] = true;
stack.push(new Position(i, j + ));
j++;
} else if ((temp[i + ][j] == ) && (p[i + ][j] == false)) {
p[i + ][j] = true;
stack.push(new Position(i + , j));
i++;
} else if ((temp[i][j - ] == ) && (p[i][j - ] == false)) {
p[i][j - ] = true;
stack.push(new Position(i, j - ));
j--;
} else if ((temp[i - ][j] == ) && (p[i - ][j] == false)) {
p[i - ][j] = true;
stack.push(new Position(i - , j));
i--;
} else {
stack.pop();
if(stack.empty()){
break;
}
i = stack.peek().row;
j = stack.peek().col;
} } Stack<Position> newPos = new Stack<Position>();
if (stack.empty()) {
System.out.println("没有路径");
} else {
System.out.println("有路径");
System.out.println("路径如下:");
while (!stack.empty()) {
Position pos = new Position();
pos = stack.pop();
newPos.push(pos);
}
} /*
* 图形化输出路径
* */ String resault[][]=new String[row+][col+];
for(int k=;k<row;++k){
for(int t=;t<col;++t){
resault[k][t]=(maze[k][t])+"";
}
}
while (!newPos.empty()) {
Position p1=newPos.pop();
resault[p1.row-][p1.col-]="#"; } for(int k=;k<row;++k){
for(int t=;t<col;++t){
System.out.print(resault[k][t]+"\t");
}
System.out.println();
} } int maze[][];
private int row = ;
private int col = ;
Stack<Position> stack;
boolean p[][] = null;
} class hello{
public static void main(String[] args){
Maze demo = new Maze();
demo.init();
demo.findPath();
}
}
java实现迷宫算法--转的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- Java面试常见算法题
1.实现字符串反转 提供七种方案实现字符串反转 import java.util.Stack; public class StringReverse { public static String re ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
随机推荐
- 捣蛋phpwind过滤器执行流程
从上一篇我们就大概就知道过滤器的定义和怎样去配置,这一节来说说执行流程 public function run($handlerAdapter = null) { $handlerAdapter != ...
- ps制作哈7海报字体
模仿也需要较强的功底和分析思路.如下面的教程,作者模仿的是电影海报字.文字构造虽不复杂,不过思路不对的话就容易走弯路.最终效果 1.先来分析文字的构造,大致由两部分组成,一部分是浮雕字,另一部分是质感 ...
- DOS 命令大全
MS DOS 命令大全 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出隐含 ...
- Linux系统github使用
命令行下使用: 1.检查ssh key cd ~/.ssh 如果提示"No such file or directory",则需要创建一个ssh key. 2.创建ssh key. ...
- bzoj2940: [Poi2000]条纹
2940: [Poi2000]条纹 条纹游戏是一个双人的游戏.所需要的物品有一个棋盘以及三种颜色的长方形条纹,这三种颜色分别是红色.绿色和蓝色.所有的红色条纹的尺寸是c*1,所有的绿色条纹的尺寸是z* ...
- URAL-1981 Parallel and Perpendicular 水题
题目链接:http://www.cnblogs.com/zhsl/p/3395868.html 水题,注意细节. //STATUS:C++_AC_31MS_333KB #include <fun ...
- Docker 入门教程(转)
add by zhj: 可以简单的认为docker是对LXC(Linux Container)封装,它提供一种比LXC高级的API.Docker使用Go语言开发,利用了Linux提供的LXC,AUFS ...
- Cocos2d-x项目移植到WP8小记
Cocos2d-x项目移植到WP8小记 作者: K.C. 日期: 10/24/2013 Date: 2013-10-24 00:33 Title: Cocos2d-x项目移植到WP8小记 Tags: ...
- mac电脑Coding显示/隐藏文件
苹果Mac OS X操作系统下,隐藏文件是否显示有很多种设置方法,最简单的要算在Mac终端输入命令.显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写): 显示Mac隐藏文件的命令:def ...
- POJ 3298 Antimonotonicity (思维)
题目链接:http://poj.org/problem?id=3298 找一个最长不要求连续的子序列,如a1 > a3 < a6 > a7 ... 举个例子模拟一下差不多明白了,a[ ...