用递归实现迷宫并且比较最短路径(java)

迷宫的制作

迷宫如下,可以看成一个二维数组,黑色的代表是墙,不能通过,黄色的代表迷宫的起点,红的代表终点。
迷宫

初始化二维数组中的数值

令:1代表墙,表示不能通过

 int [][] map=new int[7][8];
        int plan1=0;
        int plan2=0;
        for(int i=0;i<7;i++){
            map[i][0]=1;
            map[i][7]=1;
        }
        for(int j=0;j<8;j++){
            map[0][j]=1;
            map[6][j]=1;
        }
        map[1][6]=1;
        map[2][1]=1;
        map[2][2]=1;
        map[2][4]=1;
        map[3][2]=1;
        map[4][5]=1;
        map[4][3]=1;
        System.out.println("=======map====");
        for(int i=0;i<7;i++){
            for(int j=0;j<8;j++){
                System.out.print(map[i][j]+" ");
            }
            System.out.println(" ");
        }

结果为:

=======map====
1 1 1 1 1 1 1 1  
1 0 0 0 0 0 1 1  
1 1 1 0 1 0 0 1  
1 0 1 0 0 0 0 1  
1 0 0 1 0 1 0 1  
1 0 0 0 0 0 0 1  
1 1 1 1 1 1 1 1  

利用递归实现路径搜索

定义判断节点是否可以通过的方法

 1. map表示迷宫地图
 2. int i和j表示地图的哪一个节点开始搜索
 3.对此地图而言,如果到达了map[4][4]的位置,说明通路已经找到了
 4.规定:当map[i][j]为0表示该节点没有走过,当为1,表示墙,当为2 表示可以走,当为3表示节点已经走过,但是走不通
 5.在走迷宫时,需要确定一个走的策略右--》下==》上==》左,如果走不通则回溯。

方法代码:

public static boolean judgePoint(int[][] map,int i,int j){
		//设置终点,表示如果经过了终点,则说明搜索路径结束
        if(map[4][4]==2){
            return true;
        }else {
            //最先输入的这个点假设没有走过
            if(map[i][j]==0){
                //先把这个点假设可以走得通
                map[i][j]=2;
                //先向右走
                if(judgePoint(map,i,j+1)){
                    return true;
                    //向右走不通则向下走
                }else if(judgePoint(map, i+1, j)){
                    return true;
                    //如果先下走不通,则向向上走
                }else if(judgePoint(map, i-1, j)){
                    return true;
                    //如果向上走不通,则向左走
                }else if(judgePoint(map, i, j-1)){
                    return true;
                }else {
                    //都走不通,则把这个点设成走不通3
                    map[i][j]=3;
                    return false;
                }
            }
            //如果不为0,则可能为1,2,3.此时都不可以通过。
            else {
                return false;
            }
        }
    }

比较最短路径

可以看出优化方式可以从搜索的路径上开始解决,此方法的搜索路径是右–》下==》上==》左。
可以多写几种遍历的方式来进行比较,如下例中比较了两种搜索的路径不同,来通过走过的节点数,判断最短的路径。
注意,要用不同的引用来传值,也就是要重新创建一个map二维数组,来进行调用judgePoint方法。

测试代码

package com.njupt.recurrence;


/**
 * Creat with IntelliJ IDEA
 *
 * @Auther:倔强的加瓦
 * @Date:2021/07/17/15:15
 * @Description:
 */
public class MazePra {
    public static void main(String[] args) {
        //先创建一个二维数组来管理迷宫
        int[][] map = new int[7][8];
        int plan1 = 0;
        int plan2 = 0;
        for (int i = 0; i < 7; i++) {
            map[i][0] = 1;
            map[i][7] = 1;
        }
        for (int j = 0; j < 8; j++) {
            map[0][j] = 1;
            map[6][j] = 1;
        }
        map[1][6] = 1;
        map[2][1] = 1;
        map[2][2] = 1;
        map[2][4] = 1;
        map[3][2] = 1;
        map[4][5] = 1;
        map[4][3] = 1;

//这里为什么要重新创建一个地图呢?为什么用int[][] map1=map,然后用map1调用第二个方法不行呢?可以帮我回答一下吗???
        int[][] map1 = new int[7][8];
        for (int i = 0; i < 7; i++) {
            map1[i][0] = 1;
            map1[i][7] = 1;
        }
        for (int j = 0; j < 8; j++) {
            map1[0][j] = 1;
            map1[6][j] = 1;
        }
        map1[1][6] = 1;
        map1[2][1] = 1;
        map1[2][2] = 1;
        map1[2][4] = 1;
        map1[3][2] = 1;
        map1[4][5] = 1;
        map1[4][3] = 1;

        System.out.println("=======map====");
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(map[i][j] + " ");
            }
            System.out.println(" ");
        }
        System.out.println("=======map1====");
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(map1[i][j] + " ");
            }
            System.out.println(" ");
        }

        System.out.println("=====策略1,先向右,在向下=====");
        judgePoint(map, 1, 1);
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(map[i][j] + " ");
                if (map[i][j] == 2) {
                    plan1++;
                }
            }
            System.out.println(" ");
        }


        System.out.println("=====策略2,先向下,在向右=====");
        judgePoint2(map1, 1, 1);
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(map1[i][j] + " ");
                if (map1[i][j] == 2) {
                    plan2++;
                }
            }
            System.out.println(" ");
        }

        System.out.println("策略1:先右后下的策略,共走了" + plan1 + "步");
        System.out.println("策略2:先下后右的策略,共走了" + plan2 + "步");
        if (plan1 < plan2) {
            System.out.println("故策略1:先右后下的策略好,共走了" + plan1 + "步");
        } else {
            System.out.println("故策略2:先下后右的策略好,共走了" + plan2 + "步");
        }


    }

    //开始写判断节点位置的状态的方法
    // 策略1,向往右,在往下,在向上,在向左
    //规定:1表示墙,2表示节点已经走过,3表示此节点不通
    public static boolean judgePoint(int[][] map, int i, int j) {
        if (map[4][4] == 2) {
            return true;
        } else {
            //最先输入的这个点假设没有走过
            if (map[i][j] == 0) {
                //先把这个点假设可以走得通
                map[i][j] = 2;
                //先向右走
                if (judgePoint(map, i, j + 1)) {
                    return true;
                    //向下走
                } else if (judgePoint(map, i + 1, j)) {
                    return true;
                    //如果先下走不通,则向向上走
                } else if (judgePoint(map, i - 1, j)) {
                    return true;
                    //如果向上走不通,则向左走
                } else if (judgePoint(map, i, j - 1)) {
                    return true;
                } else {
                    //都走不通,则把这个点设成走不通3
                    map[i][j] = 3;
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    //策略2,先往下,后往右,在向上,在向左
    public static boolean judgePoint2(int[][] map, int i, int j) {
        if (map[4][4] == 2) {
            return true;
        } else {
            //最先输入的这个点假设没有走过
            if (map[i][j] == 0) {
                //先把这个点假设可以走得通
                map[i][j] = 2;
                //先向下走
                if (judgePoint2(map, i + 1, j)) {
                    return true;
                    //如果先下走不通,则向右走
                } else if (judgePoint2(map, i, j + 1)) {
                    return true;
                    //如果先右走不通,则向向上走
                } else if (judgePoint2(map, i - 1, j)) {
                    return true;
                    //如果向上走不通,则向左走
                } else if (judgePoint2(map, i, j - 1)) {
                    return true;
                } else {
                    //都走不通,则把这个点设成走不通3
                    map[i][j] = 3;
                    return false;
                }
            } else {
                return false;
            }
        }
    }
}

测试结果

"D:\iedal\IntelliJ IDEA 2019.3.3\jbr\bin\java.exe" "-javaagent:D:\iedal\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=32130:D:\iedal\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath E:\Java学习\数据结构与算法\DataStructure\out\production\SpareArray com.njupt.recurrence.MazePra
=======map====
1 1 1 1 1 1 1 1  
1 0 0 0 0 0 1 1  
1 1 1 0 1 0 0 1  
1 0 1 0 0 0 0 1  
1 0 0 1 0 1 0 1  
1 0 0 0 0 0 0 1  
1 1 1 1 1 1 1 1  
=======map1====
1 1 1 1 1 1 1 1  
1 0 0 0 0 0 1 1  
1 1 1 0 1 0 0 1  
1 0 1 0 0 0 0 1  
1 0 0 1 0 1 0 1  
1 0 0 0 0 0 0 1  
1 1 1 1 1 1 1 1  
=====策略1,先向右,在向下=====
1 1 1 1 1 1 1 1  
1 2 2 2 2 2 1 1  
1 1 1 0 1 2 2 1  
1 0 1 0 0 0 2 1  
1 0 0 1 2 1 2 1  
1 0 0 0 2 2 2 1  
1 1 1 1 1 1 1 1  
=====策略2,先向下,在向右=====
1 1 1 1 1 1 1 1  
1 2 2 2 0 0 1 1  
1 1 1 2 1 0 0 1  
1 0 1 2 2 0 0 1  
1 0 0 1 2 1 0 1  
1 0 0 0 0 0 0 1  
1 1 1 1 1 1 1 1  
策略1:先右后下的策略,共走了13步
策略2:先下后右的策略,共走了7步
策略2:故先下后右的策略好,共走了7Process finished with exit code 0

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值