DFS-迷宫最短路径求解

求解迷宫的问题是很常见的一种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);

    }

}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值