【数据结构与算法(java)】递归和回溯 +迷宫问题

递归和回溯

递归需要遵守的重要规则
  1. 执行一个方法时,就创建一个新的受保护的独立空间 (栈空间)
  2. 方法的局部变量是独立的,不会相互影响,比如 n 变量
  3. 如果方法中使用的是引用类型变量 (比如数组),就会共享该引用类型的数据.
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,死龟了 😃
  5. 当一个方法执行完毕,或者遇到 return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。
递归用于解决什么样的问题
  1. 各种数学问题如:8 皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子的问题 (google 编程大赛)
  2. 各种算法中也会使用到递归,比如快排,归并排序,二分查找,分治算法等.
  3. 将用栈解决的问题 --> 递归代码比较简洁

迷宫问题

public class MazeSolver {
    private static final int PATH = 2; // 路径标记
    private static final int WALL = 1; // 墙
    private static final int VISITED = 3; // 已访问标记

    public static void main(String[] args) {
        int[][] maze = {
            {1, 1, 1, 1, 1, 1, 1},
            {1, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 1, 1}
        };

        System.out.println("迷宫地图:");
        printMaze(maze);

        if (findPath(maze, 1, 1)) {
            System.out.println("\n找到路径:");
            printMaze(maze);
        } else {
            System.out.println("\n没有找到路径!");
        }
    }

    // 递归回溯法找路径
    public static boolean findPath(int[][] maze, int row, int col) {
        int rows = maze.length;
        int cols = maze[0].length;

        // 判断是否是出口(右下角)
        if (row == rows - 2 && col == cols - 2) {
            maze[row][col] = PATH;
            return true;
        }

        // 判断当前位置是否可走
        if (isValid(maze, row, col)) {
            maze[row][col] = PATH; // 标记为路径

            // 下右上左的顺序尝试
            if (findPath(maze, row + 1, col)) return true;
            if (findPath(maze, row, col + 1)) return true;
            if (findPath(maze, row - 1, col)) return true;
            if (findPath(maze, row, col - 1)) return true;

            // 如果四个方向都走不通,回溯
            maze[row][col] = VISITED;
            return false;
        }
        return false;
    }

    // 检查位置是否有效
    public static boolean isValid(int[][] maze, int row, int col) {
        return row >= 0 && row < maze.length &&
               col >= 0 && col < maze[0].length &&
               maze[row][col] == 0; // 0表示可走
    }

    // 打印迷宫
    public static void printMaze(int[][] maze) {
        for (int[] row : maze) {
            for (int cell : row) {
                switch (cell) {
                    case 0: System.out.print("  "); break; // 通路
                    case 1: System.out.print("█ "); break; // 墙
                    case 2: System.out.print("* "); break; // 路径
                    case 3: System.out.print("× "); break; // 已访问
                }
            }
            System.out.println();
        }
    }
}    
posted @ 2025-06-27 10:50  ToFuture$  阅读(25)  评论(0)    收藏  举报