递归之迷宫回溯问题

递归之迷宫回溯问题

  1. 用二维数组表示迷宫
  2. 用1表示围墙以及障碍物,
  3. 用2表示该点已经走过,经过该点,同时2表示的是该条路径是通路
  4. 用3表示该点也走过,但是该条路径是死路
  5. 走迷宫是给点一个选择路径的方向
    基本代码:
package maze.migong;

public class Maze {
    public static void main(String[] args) {
        //创建一个二维数组,用来模拟迷宫---地图
        int [][] map = new int [11][12];
        //使用1表示墙,地图四周都是用墙围起来的
        for(int i = 0 ; i < 12;i ++){
            map[0][i] = 1;
            map[10][i] = 1;
        }
        for (int i = 0; i < 11; i++){
            map[i][0] = 1;
            map[i][11] = 1;
        }
        //设置障碍物
        for (int i = 0;i < 4;i ++){
            map[5][i] = 1;
            map[i][8] = 1;
            map[i][6] = 1;
            map[2][i] = 1;
            map[i + 4][5] = 1;
        }
        //输出地图
        for(int i = 0 ;i < 11;i ++){
            for(int j = 0;j < 12;j ++ ){
                System.out.print("  " + map[i][j]);
            }
            System.out.println();
        }
    }

    /**
     *
     * @param map map表示地图
     * @param i
     * @param j  i和j分别表示开始的坐标
     * @return 如果返回值为true表示已经找到路,如果返回false那就是没有找到路
     */

    public abstract boolean setWay(int[][] map , int i , int j){

    }
}

个人思路分析:
地图

我的代码:

 public static boolean setWay(int[][] map , int i , int j){
        //这个方法的含义是什么?直接找到到达终点的路吗?
        //作为递归方法
        if(map[9][10] == 2){
            return true;
            //到达终点作为递归条件的截止
            //那原来的点都是0,你得有赋值的语句才行
        }else{
            if(map[i][j] == 0){
                //如果你传进来的点没有走过,那就以你传进来的点开始走
                map[i][j] = 2;      //假设该点可以走通,按照下--右--上--左的路径走完
                if(map[i - 1][j] == 0 && setWay(map,i + 1,j)){        //向下走
                    return true;
                }else if(map[i][j + 1] == 0 && setWay(map,i,j + 1)){      //向右走
                    return true;
                }else if(map[i + 1][j] == 0 && setWay(map,i -1,j)){       //向上走
                    return true;
                }else if(map[i][j - 1] == 0 && setWay(map,i,j - 1)){      //向左走
                    return true;
                }else{
                    //说明该点走不通是死路
                    map[i][j] = 3;
                    return false;
                }
            }else if(map[i][j] == 1){
                return false;
            }else if(map[i][j] == 2){
                return false;
            }else{
                return false;
            }
        }
    }
}

实验结果:
死路
结果分析:
陷入死循环,在应该往下走的路上,没有选择往下。
问题解决:
修改
往左走判断左边是否可以走,往下走判断下面是否可以走,判定语句错误。

第二次运行
结果
步骤图
步骤右下往上看
结果分析:

  1. 无形间有了试错功能,即使这段路走不通,也会标注为3.
  2. 同时这里是按照逆序的结果进行输出,他每一次都是调用了另外一个方法进行判断,当最终的值进行返回的时候,就在开始打印
  3. 如果一条错误的路线很长,他开了那么多栈,发现走不通,再回来,重新走,岂不是浪费很多的空间和时间。每一次的判定都要递归调用开那么多的栈。
    教程代码:
 public static boolean setWay(int[][] map , int i , int j){
        //这个方法的含义是什么?直接找到到达终点的路吗?
        //作为递归方法
        if(map[9][10] == 2){
            return true;
            //到达终点作为递归条件的截止
            //那原来的点都是0,你得有赋值的语句才行
        }else{
            if(map[i][j] == 0){
                //如果你传进来的点没有走过,那就以你传进来的点开始走
                map[i][j] = 2;      //假设该点可以走通,按照下--右--上--左的路径走完
                if(setWay(map,i - 1,j)){
                    System.out.print("  往上走");//向下走
                    return true;
                }else if(setWay(map,i,j + 1)){
                    System.out.println("  往右走");//向右走
                    return true;
                }else if(setWay(map,i + 1,j)){
                    System.out.print("  往下走");//向上走
                    return true;
                }else if(setWay(map,i,j - 1)){
                    System.out.println("  往左走");//向左走
                    return true;
                }else{
                    //说明该点走不通是死路
                    System.out.println("此路不通");
                    map[i][j] = 3;
                    return false;
                }
            }else{
                //其实只要出现三种情况1、2、3都不可以再走了,所以都是一样的,没必要单列出来
                return false;
            }
        }
    }

对比分析与总结:
1.我认为如果把走不通的路径的判定条件放在末尾,会增加程序的递归次数,每走一步都要进行条件判定都要打开很多递归,那干脆在走之前判定一下下一步的值不久可以减少程序运行时间吗?虽然你的值是在当时假定为2,但是判定是否真的为2是要有四个方向的
2. 走过的点暂时标的是2,如果说你选的路没到终点就死了,那么之前暂时标定的2就全部变成3,说明所选的路为死路
3. 方向自己可以提前设定,但是之前走过的路一定不能再走了,怎么让它不在走那?
4. 跳出递归的条件不该只有一种,如果我一开始规定的方向是先左,在右,那么该点在第一行第一段路就陷入了死循环。

发布了19 篇原创文章 · 获赞 3 · 访问量 567

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/103881628