Java 简单实现 迷宫寻找路径

项目介绍

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

项目功能

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

知识点

  1. 基础语法(if-else、for循环等)
  2. 函数调用 封装
  3. 二维数组
  4. Java面向对象思想
  5. 构造函数
  6. this关键字使用
  7. 非递归栈进行实现

实现思路

  1. 定义一个迷宫节点类型(MazeNode)的二维数组
  2. 初始化每个格子中的value值。给二维数组每个格子存放对象。对象的value值只能为0(当前格子可以走)或者1(当前格子不能走)
  3. 初始化每个格子四个方向(东南西北)是否是可走状态。根据当前节点周围四个方向格子中的value值,判断当前节点的东南西北四个方向是否可走(0是可走,1不可走)。
  4. 开始走迷宫。采用栈操作,记录行走的路径,将左上角元素入栈,判断当前栈顶元素的哪个方向可走,将其中一个可走方向进行入栈操作,直到右下角元素停止。栈中保存走过的路径。 注意: 如果遇到走入死胡同问题,此时需要将是栈顶元素并且栈顶元素的四个方向都不能行走,此时将其出栈,选择新方向再次入栈,直到右下角元素停止。

源代码

1.测试类


public class Test {
    public static void main(String[] args) {
        Maze maze = new Maze(4,4);
        maze.initValue();
        maze.initWayState();
        maze.goMaze();
        maze.show();
    } }

2.迷宫节点类

public class MazeNode {
    private int x;
    private int y;


    private int value;
    public boolean way_east;
    public boolean way_west;
    public boolean way_north;
    public boolean way_south;

    public MazeNode(){
    }

    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }


    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }



}

3.迷宫类

	public class Maze {
    private MazeNode[][] mazeNodes;
    private int row;
    private int colum;

    MyStack myStack = new MyStack();

    private static MazeNode mazeNode;

    //建立迷宫
    public Maze(int row,int colum) {
        mazeNodes = new MazeNode[row][colum];
        this.row = row;
        this.colum = colum;
    }

    //初始化迷宫路径
    public void initValue(){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入迷宫路径:");
        for(int i = 0;i<row;i++){
            for(int j = 0;j<colum;j++){
                //i   j
                mazeNodes[i][j] = new MazeNode();
                mazeNodes[i][j].setValue(scanner.nextInt());
                mazeNodes[i][j].setX(i);
                mazeNodes[i][j].setY(j);
            }
        }
    }

    //初始化每个路的状态
    public void initWayState(){
        for(int i=0;i<row;i++){
            for(int j = 0;j<colum;j++){
                //i   j
                if(mazeNodes[i][j].getValue() == 0){
                    // 东: 东边结点的value == 0   当前结点的东边方向是可走
                    if(j+1<colum && mazeNodes[i][j+1].getValue() == 0){
                        mazeNodes[i][j].way_east = true;
                    }
                    //西
                    if(j-1 >= 0 && mazeNodes[i][j-1].getValue() == 0){
                        mazeNodes[i][j].way_west = true;
                    }
                    //南
                    if(i+1 < row && mazeNodes[i+1][j].getValue() == 0){
                        mazeNodes[i][j].way_south = true;
                    }
                    //北
                    if(i-1>= 0 && mazeNodes[i-1][j].getValue() == 0){
                        mazeNodes[i][j].way_north = true;
                    }
                }
            }
        }
    }



    public void goMaze(){

        //将入口压栈
        if(mazeNodes[0][0].getValue() == 0){
            myStack.push(mazeNodes[0][0]);
        }



        while(!myStack.isEmpty()){

            //栈不为空返回栈顶元素
            mazeNode = myStack.peek();
            int x = mazeNode.getX();
            int y = mazeNode.getY();
            //栈顶元素若为出口,则跳出 while()
            if(mazeNode.getX() == row-1 && mazeNode.getY() == colum-1) {
                break;
            }
            //向西走
            if(mazeNode.way_west == true){
                //将当前节点的西节点压入栈
                myStack.push(mazeNodes[x][y-1]);
                //封当前节点向西的路
                mazeNodes[x][y].way_west = false;
                //封返回当前节点的路
                mazeNodes[x][y-1].way_east = false;

                continue;
            }

            //向东走
            else if(mazeNode.way_east == true){
                //将当前节点的东节点压入栈
                myStack.push(mazeNodes[x][y+1]);
                //封当前节点向东的路
                mazeNodes[x][y].way_east = false;
                //封返回当前节点的路
                mazeNodes[x][y+1].way_west = false;

                continue;
            }

            //向南走
            else if(mazeNode.way_south == true){
                //将当前节点的南节点压入栈
                myStack.push(mazeNodes[x+1][y]);
                //封当前节点向南的路
                mazeNodes[x][y].way_south = false;
                //封返回当前节点的路
                mazeNodes[x+1][y].way_north = false;

                continue;
            }

            //向北走
            else if(mazeNode.way_north == true){
                //将当前节点的北节点压入栈
                myStack.push(mazeNodes[x-1][y]);
                //封当前节点向北的路
                mazeNodes[x][y].way_north = false;
                //封返回当前节点的路
                mazeNodes[x-1][y].way_south = false;

                continue;
            }

            //该节点无路可走 出栈
            myStack.pop();
        }

    }

    //打印路径
    public void show(){
        //栈为空 迷宫无路径
        if (myStack.isEmpty()) {
            System.out.println("此迷宫无路径~");
            return;
        }

        //将栈中的路径标记
        while (!myStack.isEmpty()) {
            mazeNode = myStack.peek();
            mazeNode.setValue(8);
            myStack.pop();
        }

        System.out.println("迷宫路径为:");

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < colum; j++) {
                System.out.print(mazeNodes[i][j].getValue() + " ");
            }
            System.out.println();
        }
    }
}

4.栈

public class MyStack {
    private MazeNode[] array;
    private static int size;
    private static final int INITSIZE = 100;

    //初始化栈
    public MyStack(){
        array = new MazeNode[INITSIZE];
    }

    //扩容
    private void ensureCapacity(){
        if(size == array.length){
            Arrays.copyOf(array,array.length+(array.length>>1));
        }
    }
    //判断栈空不空
    public boolean isEmpty(){
            return this.size == 0;

    }

    //压栈
    public void push(MazeNode mazeNode){
        ensureCapacity();
        array[size] = mazeNode;
        size++;
    }

    //出栈
    public void pop(){
        if(isEmpty()){
            return;
        }
        size--;
    }

    //返回栈顶元素
    public MazeNode peek(){
        if(size == 0){
            throw new EmptyStackException();
        }
        return array[size-1];
    }
}
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
寻找迷宫最短路径可以用广度优先搜索(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` 分别为起点和终点的坐标。函数返回最短路径
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值