经典递归问题--走迷宫(解题代码java)
广搜代码
输入
20
0 1 0 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0
0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 1
0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1
0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 0 1
1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0
1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0
0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1
1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1
0 1 0 1 0 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0
0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0
0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0
1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0
0 0 1 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0
1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0
0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 1 1
1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0
1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1
0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0
输出
开始执行
bfs: 最小步数:43 耗时:0 毫秒
import java.util.Scanner;
public class 广搜2
{
/**
* 方向数组 上下左右
*/
static int d[][]={{0,-1},{-1,0},{0,1},{1,0}};
/**
* 坐标队列数据
*/
static int q[][];
/**
* 迷宫地图数组
*/
static int used[][];
/**
* 步数
*/
static int step = 1;
static int n = 0;
public static void main(String[] args)
{
//加载迷宫地图,初始化迷宫地图数组
Scanner in=new Scanner(System.in);
n = in.nextInt();
used=new int[n][n];
for(int i=0;i<n;i++) {
for (int j = 0; j < n; j++) {
used[i][j] = in.nextInt();
}
}
q=new int [10000000][2];
System.out.println("开始执行");
//记录程序开始时间
long startTime = System.currentTimeMillis();
//广搜。找出最短路劲,计算步数(主要程序)
bfs(0,0);
//记录程序结束时间
long endTime = System.currentTimeMillis();
//打印步数,程序耗时
System.out.println(String.format("bfs: 最小步数:%s 耗时:%s 毫秒", step,(endTime-startTime)));
}
static void bfs(int x,int y){
//r-h = 第n步有几种走法
//h=当前队列索引
//r=索引最大值
int r=0,h=0;
//在队列中记录当前坐标
q[r][0]=x;
q[r][1]=y;
r++;
//把当前坐标设置为已走过
used[x][y]=1;
int size;
while(h<r){
size=r-h;
step++;
while ((--size)>=0) {
for (int i = 0; i < 4; i++) {
//获取下一步坐标
x = q[h][0] + d[i][0];
y = q[h][1] + d[i][1];
//判断下一步可行或已走过
if (x >= 0 && x < n && y >= 0 && y < n && used[x][y] != 1) {
//到终点
if (x == n-1 && y == n-1) {
return;
}
//把下一步设置为已走过
used[x][y] = 1;
q[r][0] = x;
q[r][1] = y;
r++;
}
}
h++;
}
}
}
}
深搜代码
输入
20
0 1 0 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0
0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 1
0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1
0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 0 1
1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0
1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0
0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1
1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1
0 1 0 1 0 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0
0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0
0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0
1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0
0 0 1 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0
1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0
0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 1 1
1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0
1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0
1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1
1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1
0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0
输出
开始执行
dfs: 最小步数:43 耗时:1235 毫秒
import java.util.Scanner;
/*
0 1 0 0 0
0 1 0 1 0
0 0 0 1 0
0 1 1 1 0
0 0 0 1 0
相对于广度优先访问,深度优先的方式更像是一条路走到黑,走不下去了再回到上个路口选择另外一条路。
*/
public class 深搜2
{
/**
* 方向数组 上下左右
*/
static int d[][]={{0,-1},{-1,0},{0,1},{1,0}};
/**
* 迷宫地图数组
*/
static int used[][];
static int n = 0;
/**
* 步数 初始化为int最大值
*/
static int step = Integer.MAX_VALUE;
public static void main(String[] args){
//加载迷宫地图,初始化迷宫地图数组
Scanner in=new Scanner(System.in);
n = in.nextInt();
used=new int[n][n];
for(int i=0;i<n;i++) {
for (int j = 0; j < n; j++) {
used[i][j] = in.nextInt();
}
}
//设置出发点 从左上角也就是(0,0)坐标开始
int x=0,y=0;
System.out.println("开始执行");
//记录程序开始时间
long startTime = System.currentTimeMillis();
//深搜。找出最短路劲,计算步数(主要程序)
dfs(x,y,1);
//记录程序结束时间
long endTime = System.currentTimeMillis();
//打印步数,程序耗时
System.out.println(String.format("dfs: 最小步数:%s 耗时:%s 毫秒", step,(endTime-startTime)));
}
/**
* 深搜
* @param x x坐标 (used一维数组索引)
* @param y y坐标 (used二维数组索引)
* @param dpt 深搜深度 (等于步数)
*/
static void dfs(int x,int y,int dpt){
//判断当前坐标是不是墙壁或者已走过
if(x<0||x>=n||y<0||y>=n||used[x][y]==1){
return;
}
//走到终点。对比步数。记录最小步数
if(x==n-1&&y==n-1){
step = step > dpt ? dpt : step;
}
//从当前节点,往上下左右四个方向寻找下一步可行点
for (int i=0;i<4;i++){
int xx = x+d[i][0]; //下一步的x坐标
int yy = y+d[i][1]; //下一步的y坐标
used[x][y]=1; //把当前坐标设置为已走过
//下一步
dfs(xx,yy,dpt+1);
//回溯
used[x][y]=0; //还原当前坐标设置为未走过
}
}
}