博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA算法:走迷宫回溯算法设计(JAVA版本)
阅读量:4039 次
发布时间:2019-05-24

本文共 3739 字,大约阅读时间需要 12 分钟。

JAVA算法:走迷宫回溯算法设计(JAVA版本)

迷宫数组

     int[][] maze = {

                {0, 1, 0, 0, 0},
                {0, 1, 0, 1, 0},
                {0, 0, 0, 0, 0},
                {0, 1, 1, 1, 0},
                {0, 0, 0, 1, 0}
        };

 

算法思路

将迷宫问题对应为二维数组,数组中只有两种值0和1,其中0,1分别表示通路和墙。

不过在解决这个问题的时候一般要在最外面添加一个围墙,这里设置每个围墙都为1,这样有利于防止当走到了迷宫的出口处还会向前走,这个并不一定,只是最一般的方法,也是最有利于理解的方法。

这里的利用到了回溯法,需要走到了一个位置,然后向四处试探,如果有一个方向可以走了就将当前的点压入栈,并且标记当前点以便于区分是否走过,如果四处都无出路,只需要回到前一个走到的点,然后从前一个点再换一个方向重新走。

算法设计

设计一个Position类,用来表示迷宫中位置点(坐标)

package com.bean.algorithm.maze;public class Position {	public int row;	public int col;	public Position(int row, int col) {		this.col = col;		this.row = row;	}	public Position() {		row = 0;		col = 0;	}	public String toString() {		return "(" + (row - 1) + " ," + (col - 1) + ")";	} // 这里由于四周围上了墙,所以这里的输出就要在原来的基础上减一}

设计迷宫类 Maze

package com.bean.algorithm.maze;import java.util.Stack;public class Maze {	private int[][] maze = null;	private Stack
stack = null; // 创建一个栈用于存储状态 private int row; // 行数 private int col; boolean[][] p = null; // 这里的p是用来标记已经走过的点,初始化为false public boolean end(int i, int j) { return i == row && j == col; } public Maze(int[][] maze) { stack = new Stack
(); row = maze[0].length;// 行数 col = maze.length; // 列数 p = new boolean[row + 2][col + 2]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { p[i][j] = false; // 初始化 } } this.maze = maze; } public void findPath() { // 创建一个新的迷宫,将两边都围上墙,也就是在四周都填上1的墙,形成新的迷宫,主要的目的就是防止走到迷宫的边界的出口的位置还会继续向前走 // 因此需要正确的判断是否在边界线上,所以要在外围加上一堵墙, int[][] temp = new int[row + 2][col + 2]; for (int i = 0; i < row + 2; i++) { for (int j = 0; j < col + 2; j++) { temp[0][j] = 1; // 第一行围上 temp[row + 1][j] = 1; // 最后一行围上 temp[i][0] = temp[i][col + 1] = 1; // 两边的围上 } } // 将原始迷宫复制到新的迷宫中 for (int i = 0; i < row; ++i) { for (int j = 0; j < col; ++j) { temp[i + 1][j + 1] = maze[i][j]; } } int i = 1; int j = 1; p[i][j] = true; stack.push(new Position(i, j)); // 这里是是将走到的点入栈,然后如果前后左右都走不通的话才出栈 while (!stack.empty() && !end(i, j)) { // 下面就开始在四周试探,如果有路就向前走,顺序分别是右,下,上,左,当然这是随便定义的,不过一般都是现向下和右的 if (temp[i][j + 1] == 0 && p[i][j + 1] == false)// 这里如果不在四周加上墙,那么在到达边界判断的时候就会出现超出数组的索引的错误,因为到达边界再加一就会溢出 { p[i][j + 1] = true; stack.push(new Position(i, j + 1)); j++; } else if (temp[i + 1][j] == 0 && p[i + 1][j] == false)// 如果下面可以走的话,讲当前点压入栈,i++走到下一个点 { p[i + 1][j] = true; stack.push(new Position(i + 1, j)); i++; } else if (temp[i][j - 1] == 0 && p[i][j - 1] == false) { p[i][j - 1] = true; stack.push(new Position(i, j - 1)); j--; } else if (temp[i - 1][j] == 0 && p[i - 1][j] == false) { p[i - 1][j] = true; stack.push(new Position(i - 1, j)); i--; } else // 前后左右都不能走 { System.out.println(i + "---------" + j); stack.pop(); // 这个点不能走通,弹出 if (stack.empty()) // 如果此栈中已经没有点了,那么直接跳出循环 { System.out.println("没有路径了,出不去了"); return; // 直接退出了,下面就不用找了 } i = stack.peek().row; // 获得最新点的坐标 j = stack.peek().col; } // 如果已经到达了边界,那么直接可以出去了,不需要继续向前走了,这里是规定边界的任意为0的位置都是出口 // 如果不加这个判断的话,那么当到达边界的时候,只有走到不能再走的时候才会输出路线,那种线路相对这个而言是比较长的 if (j == temp[0].length - 2) { // 如果已经到达边界了,那么当前的位置就是出口,就不需要再走了 Stack
pos = new Stack
(); System.out.println("路径如下:"); for (int count = 0; count < stack.size(); count++) { System.out.println(stack.elementAt(count)); } } } } public static void main(String args[]) { int[][] maze = { { 0, 1, 0, 0, 0 }, { 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0 }, { 0, 0, 0, 1, 0 } }; Maze main = new Maze(maze); main.findPath(); }}

程序运行结果:

路径如下:

(0 ,0)
(1 ,0)
(2 ,0)
(2 ,1)
(2 ,2)
(2 ,3)
(2 ,4)
路径如下:
(0 ,0)
(1 ,0)
(2 ,0)
(2 ,1)
(2 ,2)
(2 ,3)
(2 ,4)
(3 ,4)
路径如下:
(0 ,0)
(1 ,0)
(2 ,0)
(2 ,1)
(2 ,2)
(2 ,3)
(2 ,4)
(3 ,4)
(4 ,4)

 

转载地址:http://nitdi.baihongyu.com/

你可能感兴趣的文章
zookeeper
查看>>
Idea导入的工程看不到src等代码
查看>>
技术栈
查看>>
Jenkins中shell-script执行报错sh: line 2: npm: command not found
查看>>
8.X版本的node打包时,gulp命令报错 require.extensions.hasownproperty
查看>>
Jenkins 启动命令
查看>>
Maven项目版本继承 – 我必须指定父版本?
查看>>
Maven跳过单元测试的两种方式
查看>>
通过C++反射实现C++与任意脚本(lua、js等)的交互(二)
查看>>
利用清华镜像站解决pip超时问题
查看>>
[leetcode BY python]1两数之和
查看>>
微信小程序开发全线记录
查看>>
Centos import torchvision 出现 No module named ‘_lzma‘
查看>>
PTA:一元多项式的加乘运算
查看>>
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
Django 的Error: [Errno 10013]错误
查看>>