0
点赞
收藏
分享

微信扫一扫

夜深人静写算法【递归】

1. 递归的概念

1.1 文字描述

1.2 图示

diguijiecheng

2. 递归的应用场景

2.1 递归能解决什么样的问题

2.1.1 各种数学问题

2.1.2 各种算法

2.1.3 解决栈的问

2.2 递归需要遵守的重要规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  2. 方法的局部变量是独立的,不会相互影响, 比如num变量【num:图示里的变量】
  3. 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据.【引用类型变量会都放到堆内存里】
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,出现【栈溢出】StackOverflowError,死循环)
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

3.迷宫回溯

3.1思路分析【图示】

image-20220217022158960

3.2 代码实现

package recursion;

import java.util.Random; 

/**
 * @Author 小源同学
 * @Date 2022 02 17 01 59
 * @Describe 迷宫回溯
 **/
public class MazeBacktracking {
    public static void main(String[] args) {
        int y = 8;
        int x = 7;
        int[][] ints = initMap(y, x);
        System.out.println("初始化迷宫:");
        soutInt(ints);

        System.out.println("迷宫回溯后的路径:");
        findMapPath(ints, 1, 1, x, y);
        soutInt(ints);
    }

    /**
     * 迷宫回溯的核心代码
     * 1. 设置终点为map[y-2][x-2]
     * 2. 使用0:表示未走过;使用1:表示墙体;使用2:表示通路;使用3:表示不可通行
     * 3. 寻路策略:下->右->上->左,如果路不通,回溯
     *
     * @param map 初始化的地图
     * @param i   开始的横坐标比如:map[1][1]
     * @param j   开始的纵坐标比如:map[1][1]
     * @param x   地图的列数
     * @param y   地图的行数
     * @return 找到通路返回true, 如果没有找到就返回false
     */
    private static boolean findMapPath(int[][] map, int i, int j, int x, int y) {
        if (map[y - 2][x - 2] == 2) {//表示已经找到通路,直接返回,如果再回溯,就退出回溯
            return true;
        } else {
            if (map[i][j] == 0) {//如果该点没有走过
                //假设这个点可以走
                map[i][j] = 2;
                //然后再判断这个点是否可以通向其他点
                if (findMapPath(map, i + 1, j, x, y)) {//【根据策略】向下走
                    return true;
                } else if (findMapPath(map, i, j + 1, x, y)) {//【根据策略】向右走
                    return true;
                } else if (findMapPath(map, i - 1, j, x, y)) {//【根据策略】向上走
                    return true;
                } else if (findMapPath(map, i, j - 1, x, y)) {//【根据策略】向左走
                    return true;
                } else {//证明这个点不可以走
                    map[i][j] = 3;
                    return false;
                }
            } else {//ap[i][j] != 0 那么这个点的值可能为 1 2 3,则不再继续
                return false;

            }
        }
    }

    /**
     * 初始化迷宫地图,用二维数组(int[8][7])表示,根据需求创建一个地图
     *
     * @param x 列
     * @param y 行
     * @return 返回初始化的地图
     */
    private static int[][] initMap(int y, int x) {
        //使用1:表示墙体
        //使用2:表示通路
        //使用3:表示不可通行
        int[][] map = new int[y][x];
        //初始化上下的墙体:遍历列【x】
        for (int i = 0; i < x; i++) {
            map[0][i] = 1;
            map[y - 1][i] = 1;
        }
        //初始化左右墙体:遍历行【y】
        for (int j = 0; j < y; j++) {
            map[j][0] = 1;
            map[j][x - 1] = 1;
        }
        //随机创建阻挡
        Random rn = new Random();
        //2到y-1之间的数字
        int randomY = rn.nextInt(y - 2) + 2;
        //添加到迷宫里
        //1到3之间的数字
        //如果要修改的话,根据设定的迷宫行与列进行修改
        map[rn.nextInt(y - 2) + 2][rn.nextInt(x-2) + 1] = 1;
        map[rn.nextInt(y - 2) + 2][rn.nextInt(x-2) + 1] = 1;
        return map;
    }

    //打印输出 int[][]
    private static void soutInt(int[][] ints) {
        for (int[] anInt : ints) {
            for (int i : anInt) {
                System.out.print(i + "   ");
            }
            System.out.println();
        }
    }
}
举报

相关推荐

0 条评论