超详解的迷宫问题(Java版)

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了超详解的迷宫问题(Java版)相关的知识,希望对你有一定的参考价值。

问题描述

给定一个M*N 的迷宫图、入口与出口、行走规则。求一条从指定入口到出口的路径(这里M=8,N=8),所求路径必须是简单路径,即路径不重复 (为了方便算法起见,在整个迷宫外围加上一堵墙)

在这里插入图片描述

算法实现

use Stack

从入口 (i, j) 出发,共有 上(i-1, j)下(i+1, j)左(i, j-1)右(i, j+1)四个方向选择

考虑使用栈,从当前位置分别向四个方向寻找,可行的点,如果有可行的点就入栈,若无可行的点,则将栈顶的元素 pop 修改 值为 -1 代表不可行。

代码展示

import java.util.Stack;

public class 迷宫问题 {
    static int[][] matrix;
    public static void main(String[] args) {

        // 1 代表围墙,2代表走过,-1代表该点不通,避免下次重复搜索
        matrix = new int[][] {
                    {1,1,1,1,1,1,1,1,1,1},
                    {1,0,0,1,0,0,0,1,0,1},
                    {1,0,0,1,0,0,0,1,0,1},
                    {1,0,0,0,0,1,1,0,0,1},
                    {1,0,1,1,1,0,0,0,0,1},
                    {1,0,0,0,1,0,0,0,0,1},
                    {1,0,1,0,0,0,1,0,0,1},
                    {1,0,1,1,1,0,1,1,0,1},
                    {1,1,0,0,0,0,0,0,0,1},
                    {1,1,1,1,1,1,1,1,1,1}
                };
        // 初始化栈
        Stack<int[]> stack = new Stack<>();
        // 初始化四个方向 上下左右
        int[] x = {-1, 1, 0, 0};
        int[] y = {0, 0, -1, 1};
        // (1,1)作为起点
        stack.push(new int[]{1, 1});
        // 修改(1,1)的值为 2,代表已经走过
        matrix[1][1] = 2;
        printResult();
        while (!stack.isEmpty()) {  // 栈不为空就一直循环
            int[] cur = stack.peek();  // 获取当前点,cur[0]:代表 横坐标 cur[1]:代表纵坐标
            // 到达终点
            if (cur[0] == 8 && cur[1] == 8) {
                printResult();
                break;
            }
            // 从当前点向四个方向找可行的点
            int i;
            for (i = 0; i < 4; i++) {
                int row = cur[0]+x[i];
                int column = cur[1]+y[i];

                // 判断当前方向是否可以通过
                if (matrix[row][column] == 0) {
                    stack.push(new int[]{row, column});
                    matrix[row][column] = 2;
                    break;
                }
            }
            // 如果未找到可行方向,则将栈顶元素 pop,修改为 -1
            if (i == 4) {
                cur = stack.pop();
                matrix[cur[0]][cur[1]] = -1;
            }
        }
    }
    // 输出迷宫图,显示路线
    public static void printResult() {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j]+" ");
            }
            System.out.println();
        }
    }
}

recursion

使用递归每次都向四个方向探索,若某条路不通,则回溯,并修改该点值为-1,反之修改2,代表走过的路。

代码展示

package Algorithm;
import java.util.Stack;

public class 迷宫问题 {
    static int[][] matrix;
    public static void main(String[] args) {

        // 1 代表围墙,2代表走过,-1代表该点不通,避免下次重复搜索
        matrix = new int[][] {
                   {1,1,1,1,1,1,1,1,1,1},
                   {1,0,0,1,0,0,0,1,0,1},
                   {1,0,0,1,0,0,0,1,0,1},
                   {1,0,0,0,0,1,1,0,0,1},
                   {1,0,1,1,1,0,0,0,0,1},
                   {1,0,0,0,1,0,0,0,0,1},
                   {1,0,1,0,0,0,1,0,0,1},
                   {1,0,1,1,1,0,1,1,0,1},
                   {1,1,0,0,0,0,0,0,0,1},
                   {1,1,1,1,1,1,1,1,1,1}
               };
        // 起点 (1,1)终点(8,8),可以灵活设置
        recursion(1, 1);
        printResult();
    }
    // 递归方法
    public static boolean recursion(int i, int j) {
        // 递归结束条件,代表已到达终点(8,8)
        if (matrix[8][8] == 2) {
            return true;
        }
        // 判断4个方向是否可行,一个方向可行就往深度递归,否则:回溯
        if (matrix[i][j] == 0) {  // 如果该点未访问过,则从该点探索
            matrix[i][j] = 2;
            if (recursion(i-1, j)) {  // 如果上方可行,则继续探索
                return true;
            } else if (recursion(i+1, j)) {  // 下方
                return true;
            } else if (recursion(i, j-1)) {  // 左方
                return true;
            } else if (recursion(i, j+1)) {  // 右方
                return true;
            } else {  // 如果四个方向 都不行说明该递归分支,不行,回溯
                // 该点走不通,标记 -1,避免重复访问
                matrix[i][j] = -1;
                return false;
            }
        } else {
            return false;
        }
    }


    // 输出迷宫图,显示路线
    public static void printResult() {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j]+" ");
            }
            System.out.println();
        }
    }
}

参考博客
Link
Link

感谢

技术开源,知识共享,分享快乐

站在巨人的肩膀上,前进!

小白梦想当大牛

加油!

以上是关于超详解的迷宫问题(Java版)的主要内容,如果未能解决你的问题,请参考以下文章

详解Java递归(Recursion)通过递归解决迷宫回溯及八皇后问题

洛谷 P1141- 01 迷宫问题(Java版)

[Algorithm]Java 版递归算法解迷宫问题哈诺塔问题八皇后问题

51-迷宫- java版dfs和bfs

伪元素使用详解(超详细版)

伪元素使用详解(超详细版)