java实现寻找迷宫路径

迷宫描述:一个网格迷宫由n行m列的单元格组成,每个单元格要是空地(用0表示),或者是障碍物(用1表示)。寻找一条从起点到终点的移动序列,只能上下左右移动到相邻单元格。任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外。起点为左上角和终点右下角。

问题:解决迷宫路径查找问题,寻找一条从左上角迷宫入口到右下角迷宫出口的一条有效路径,0代表可走,1代表不能行走,找到请输出最终的迷宫和路径信息,找不到请输出不存在有效路径。
迷宫示例

0 1 1 1 1
0 1 1 1 1
0 0 0 0 1
1 1 1 0 1
1 1 1 0 0

问题分析
迷宫可以用二维数组表示,迷宫的起点和终点已经确定,为左上角到右下角。现在需要设计一个程序,可以让它自动从左上角走到右下角,如果走进死路了,可以退回去,换一条路走。需要解决的问题有:

  • 如何确定哪个方向可以走,如果有多个方向可以走,怎么确定走哪个?
  • 如何让程序一直走下去?进入死路了如何退出来?
  • 如何让程序停下来?

显然可走的方向有四个,上下左右。走的顺序可以提前设定,比如顺序为:→ ↓ ← ↑。什么方向不能走?节点为1的,和来的方向的节点。
可以用栈来存储当前走过的节点,如果这个节点四个方向都不能走,则将栈顶节点出栈,回退到上一个位置。
如何让程序一直走下去?这里需要一个循环结构,首先想到的就是while循环,现在需要设计的是内部的处理过程和循环条件。
在这里插入图片描述

现在已经有了一个大致的思路,还未解决的问题有:

  • 如何让节点不会回到来的位置。
  • 如何让节点不会又走进之前走过的死路。

判断节点可以走的条件是该位置为0,所以可以把节点走过的位置的值改为2,走入死路后,回退时可以将该位置改为1,这样就不会再次走进这条路。
现在基本解决了大多数的问题,可以开始写了。
首先需要一个节点类,它要存储当前节点的位置。

public class Point {
    public int[] pointArray;//存储当前位置坐标
 
    public Point(int x,int y){
        pointArray=new int[2];
        pointArray[0]=x;
        pointArray[1]=y;
    }
}

一个节点操作类

public class Labyrinth {
    Scanner scanner=new Scanner(System.in);
    Stack<Point> stack=new Stack<>();
    int[][] arr;
    public  Labyrinth(){


    }

    public   int[][] inputNum(){

        System.out.println("请输入迷宫行列数:");
        int line = scanner.nextInt();//行
        int row = scanner.nextInt();//列

        System.out.println("请输入迷宫:");

        int[][] arr=new int[line][row];

        for(int i=0;i<line;i++){
            for(int k=0;k<row;k++){
                arr[i][k]=scanner.nextInt();
            }
        }
        return  arr;

    }

    public  void  show(){
        for(int i=0;i<arr.length;i++){
            System.out.println(Arrays.toString(arr[i]));
        }
    }


    public void findPath(){//核心方法
        int line=arr.length;
        int row=arr[0].length;
        boolean flag=true;
        Point point=new Point(0,0);
        stack.push(point);
        boolean anser=true;
        while (flag){
            if(stack.empty()){
               anser=false;
               break;
            }
           Point point1=stack.peek();
           int x=point1.pointArray[0];
           int y=point1.pointArray[1];
           if(x==line-1&&y==row-1&&arr[line-1][row-1]==0){
               arr[line-1][row-1]=2;
               break;
           }
           int index=canRun(x,y);
           operation(index,x,y);
       
        }

    }
    //找到可以走的方向后,对该方向的节点做入栈操作,若该节点四个方向都走不了,则出栈该节点
    public void operation(int index,int x,int y){
        switch (index){
            case 1:
                Point point1=new Point(x,y+1);
                stack.push(point1);
                arr[x][y]=2;
                break;
            case 2:
                Point point2=new Point(x+1,y);
                stack.push(point2);
                arr[x][y]=2;
                break;
            case 3:
                Point point3=new Point(x,y-1);
                stack.push(point3);
                arr[x][y]=2;
                break;
            case 4:
                Point point4=new Point(x-1,y);
                stack.push(point4);
                arr[x][y]=2;
                break;
            case 5://四个方向都走不了
                arr[x][y]=1;
                stack.pop();
                break;

        }
    }
//判断哪个方向可以走
    public int canRun(int x,int y){
      if(y+1<arr[0].length&&arr[x][y+1]==0){
          return 1;
      }
      if(x+1<arr.length&&arr[x+1][y]==0){
          return 2;
      }
      if(y-1>=0&&arr[x][y-1]==0){
          return 3;
      }
      if(x-1>=0&&arr[x-1][y]==0){
            return 4;
      }
      return 5;//四个方向都走不了
    }

    public static void main(String[] args) {
        Labyrinth labyrinth=new Labyrinth();
       labyrinth.arr=labyrinth.inputNum();
       labyrinth.findPath();
       labyrinth.show();

    }



}

测试:
在这里插入图片描述
结果:
在这里插入图片描述
该方法缺点:只能找到一条路径,后续会更新优化后的方法

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
寻找迷宫最短路径可以用广度优先搜索(BFS)来实现。BFS 从起点开始,逐层向外扩展搜索,直到找到终点或者搜索完所有可达点。在搜索过程中,需要记录每个点的距离和前驱节点,以便找到最短路径。 下面是用 BFS 实现寻找迷宫最短路径的大致步骤: 1. 定义一个队列,将起点入队。 2. 定义一个二维数组,记录每个点是否被访问过,并初始化为 false。 3. 定义一个二维数组,记录每个点的距离和前驱节点,并初始化为 -1 和 null。 4. 从队列中取出一个点,将其标记为已访问。 5. 遍历该点的所有邻居,如果邻居没有被访问过,则将其入队,并更新距离和前驱节点。 6. 如果终点被标记为已访问,则找到了最短路径,可以根据前驱节点数组回溯路径。 下面是一个简单的 Java 代码实现: ```java import java.util.*; public class ShortestPath { static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // 上下左右四个方向 public static List<int[]> bfs(char[][] maze, int[] start, int[] end) { int m = maze.length, n = maze[0].length; boolean[][] visited = new boolean[m][n]; int[][] distance = new int[m][n]; int[][] prev = new int[m][n]; for (int i = 0; i < m; i++) { Arrays.fill(distance[i], -1); Arrays.fill(prev[i], -1); } Queue<int[]> queue = new LinkedList<>(); queue.offer(start); visited[start[0]][start[1]] = true; distance[start[0]][start[1]] = 0; while (!queue.isEmpty()) { int[] cur = queue.poll(); for (int[] dir : dirs) { int ni = cur[0] + dir[0], nj = cur[1] + dir[1]; if (ni >= 0 && ni < m && nj >= 0 && nj < n && maze[ni][nj] != '#' && !visited[ni][nj]) { visited[ni][nj] = true; distance[ni][nj] = distance[cur[0]][cur[1]] + 1; prev[ni][nj] = cur[0] * n + cur[1]; if (ni == end[0] && nj == end[1]) { return getPath(prev, start, end, n); } queue.offer(new int[]{ni, nj}); } } } return new ArrayList<>(); } private static List<int[]> getPath(int[][] prev, int[] start, int[] end, int n) { List<int[]> path = new ArrayList<>(); int cur = end[0] * n + end[1]; while (cur != start[0] * n + start[1]) { int pi = cur / n, pj = cur % n; path.add(new int[]{pi, pj}); cur = prev[pi][pj]; } path.add(start); Collections.reverse(path); return path; } public static void main(String[] args) { char[][] maze = { {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}, {'#', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#'}, {'#', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#'}, {'#', ' ', ' ', ' ', '#', ' ', ' ', ' ', ' ', '#'}, {'#', ' ', ' ', ' ', ' ', ' ', '#', '#', ' ', '#'}, {'#', ' ', '#', '#', '#', '#', ' ', ' ', ' ', '#'}, {'#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#'}, {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}, }; int[] start = {1, 1}; int[] end = {6, 8}; List<int[]> path = bfs(maze, start, end); System.out.println("最短路径:"); for (int[] p : path) { System.out.println("(" + p[0] + ", " + p[1] + ")"); } } } ``` 注意,以上代码中的 `maze` 是一个二维迷宫数组,'#' 表示墙,' ' 表示空地。`start` 和 `end` 分别为起点终点的坐标。函数返回最短路径

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值