求解迷宫的问题是很常见的一种DFS算法。例如如图:找到从入口到出口的最短路径,有障碍物的地方不能走。
解决这种问题首先是要建立出数据模型来存放数据。然后再进行逻辑分析。
我们可以定义一个二维数组来存放数据
//迷宫数据 0=空位,1=入口,2=出口,8=障碍物
public static int [][] mazeData = {
{1,8,0,0,0},
{0,8,0,8,0},
{0,0,0,8,0},
{0,8,0,8,0},
{0,8,0,0,2},
};
然后棋子走的情况总共有四种,就是上下左右,我们可以根据坐标的加减实现位移。所以再定义一个二维数组,来实现移动
public static int[][] direct = {
{1,0},//右
{-1,0},//左
{0,-1},//上
{0,1},//下
};
在进行“走迷宫”的过程中,我们还需要定义另一个数组,来保存我们哪些位置是已经走过了的,走过的我们就不在走了,如果没有这个条件的话,会一种循环无法跳出。还需要注意迷宫的边界,和障碍物的坐标。
这种算法一般出错后,如果找不出逻辑的问题,可以简化数据模型,从简单开始测试,调试错误。
完整代码
import java.lang.reflect.Parameter;
/**
* @Author 超厉害的我啊
* @date 2020/6/1 08:51:29
*/
public class A09DFS_Maze {
public static final int STONE = 8;
public static final int ENDPOINT=2;
public static int startX;
public static int startY;
// public static int[] directRight={1,0};
// public static int[] directLeft={-1,0};
// public static int[] directTop={0,-1};
// public static int[] directBottom={0,1};
public static int[][] direct = {
{1,0},
{-1,0},
{0,-1},
{0,1},
};
//迷宫横纵坐标标记
private static int xMax=0;
private static int yMax=0;
private static int[][] walked=null;
//定义变量记录走出迷宫最少的步数
private static int stepMin =Integer.MAX_VALUE;
//找到出口的方法
public static void findExit(int[][] datas){
findStartPos(datas);
xMax=datas[0].length;
yMax=datas.length;
walked=new int[yMax][xMax];
walked[startY][startX] = 1;
//只要调用一次dfs就相对于走了一步,所以一开始传入1
findExitDFS(datas,startX,startY,1);
System.out.println("最小路径是:"+stepMin+"步");
}
private static void findExitDFS(int[][] datas, int xCur, int yCur, int step){
// System.out.println("移动到了 "+xNew+","+yNew+"此位置:"+datas[yNew][xNew]);
for (int i = 0; i < direct.length; i++) {
int xNew=xCur+direct[i][0];
int yNew=yCur+direct[i][1];
//防止走出迷宫界限之外
if(xNew>=xMax||yNew>=yMax ||xNew < 0 || yNew < 0){
continue;
}
//确定是否已经走过
if(walked[yNew][xNew]==1){
continue;
}
//是否为墙
if(datas[yNew][xNew]==STONE){
continue;
}
//出口
if(datas[yNew][xNew] ==ENDPOINT){
if(step<stepMin){
stepMin=step;
}
System.out.println("########### 找到出口坐标:"+xNew+","+yNew+"走了:"+step+"步");
return;
}
System.out.println("移动到了 "+xNew+","+yNew+"此位置:"+datas[yNew][xNew]);
walked[yNew][xNew] = 1;
findExitDFS(datas,xNew,yNew,step+1);
}
}
//找到起点坐标
private static void findStartPos(int[][] datas){
for(int y=0;y<datas.length;y++){
for (int x=0;x<datas[y].length;x++){
if(datas[y][x]==1){
startX=x;
startY=y;
System.out.println("起点坐标"+startX+","+startY);
return;
}
}
}
}
public static void main(String[] args) {
findExit(GeoData.mazeData);
}
}