从此篇开始讲述数据结构与算法的相关知识与应用。
走迷宫问题是一个比较经典也比较常见的问题,这里使用递归加回溯的思路解题。
下面是我准备的迷宫(用word画的):
说明:这是一个8*8的表格,我们用二维数组存储(char[][] map),其中,左上角起点坐标为(1,1),右下角终点处的坐标为(6,6)。灰色阴影部分作为墙是不能走的,白色部分表示可走。墙体我们用 * 表示,走完后我们用字符 0 标注出一条路径,另外还有一些走不通的路径用 # 标注。代码如下:
import java.util.Arrays;
public class Maze {
static int ROW = 8;//迷宫的大小在这里指定,ROW表示行
static int COL = 8;//表示列
public static void main(String[] args) {
//初始化迷宫
char[][] maze = new char[ROW][COL];
for (char[] link : maze){
Arrays.fill(link,' ');//先把所有的地方用空格填充
}
//把迷宫的围墙画上
for (int i = 0; i < ROW; i++) {
maze[i][0] = '*';
maze[i][ROW - 1] = '*';
}
for (int i = 0; i < COL; i++) {
maze[0][i] = '*';
maze[COL - 1][i] = '*';
}
//再把里面的围墙画上
maze[1][3] = '*';
maze[2][5] = '*';
maze[3][2] = '*';
maze[3][3] = '*';
maze[3][5] = '*';
maze[4][4] = '*';
maze[5][2] = '*';
maze[5][4] = '*';
maze[5][1] = '*';
maze[5][6] = '*';
maze[6][4] = '*';
//把画好的迷宫显示出来
// showMaze(maze);
setWay(maze,1,1);//开始走迷宫
showMaze(maze);//走完以后再把标注好的迷宫显示出来
}
//核心代码,开始寻路
//map是当前迷宫的地图
//i和j表示出发位置
//从左上角(1,1)出发,到右下角表示找到出路(ROW - 2,COL - 2)
//空格表示没有走过,'*'表示墙,'0'表示可以走,'#'表示此点已经探测过走不通
//探测方向顺序是 下->右->上->左
public static boolean setWay(char[][] map,int i,int j){
//如果右下角的值(ROW - 2,COL - 2)的值变为'0',表示通路已经找到.
if(map[ROW - 2][COL - 2] == '0'){
//也可以在这里修改终点,可以让方法带进来
return true;
}else{
if(map[i][j] == ' '){//该点还没有走过
map[i][j] = '0';//当前点置0,假定该点能走通
if(setWay(map,i + 1,j )){//向下走
return true;
}else if(setWay(map,i,j + 1)){//向右走
return true;
}else if(setWay(map,i - 1,j)){//向上走
return true;
}else if(setWay(map,i,j - 1)){//向左走
return true;
}
else{//表示此路不通,开始回溯
map[i][j] = '#';
return false;
}
}else{
return false;
}
}
//最终完成后,迷宫的地图就被标注出来
}
//这个方法输出迷宫
public static void showMaze(char[][] maze){
for (int i = 0; i < maze.length; i++) {
for (int j = 0; j < maze.length; j++) {
System.out.printf("%2c ",maze[i][j]);
}
System.out.println();
}
}
}
好了,迷宫就走完了,探测方向的顺序不同,最终路径也会有所不同,我为了体现回溯的过程特地画迷宫的时候按照探测方向的先后顺序先引到一条死路,然后回溯。
代码并不难,写出来也比较好理解。主要是要体会递归+回溯的算法思想,并能做一些应用。
欢迎指正。。。
更多请访问github链接…