走迷宫的 最笨的遍历算法 高手可以不用看了
初学java的 可以参考一下 我的注释还算详细
定义了一个二维字符数组 存储迷宫
#代表不能走的地方 [空格]代表可以走的路
代码 Java
import java.util.LinkedList;
public class Maze {
private static char[][] maze; // 迷宫存储
private static boolean solvable = true; // 迷宫是否有解
// 方向常量
private static final int[] DIR_UP = { 0, -1 };
private static final int[] DIR_DOWN = { 0, 1 };
private static final int[] DIR_LEFT = { -1, 0 };
private static final int[] DIR_RIGHT = { 1, 0 };
// 走步栈
private LinkedList<Step> steps = new LinkedList<Step>();
// 构造方法
public Maze(char[][] maze, int row, int col) {
this.maze = maze;
// 创建迷宫遍历根节点
Step r = new Step(row, col);
maze[row][col] = 'S';
// 将新节点存入走步栈
steps.add(r);
}
// 解迷宫
public boolean solve() {
while (true) {
// 得到上一个节点
Step s = steps.getLast();
// 得到下一个节点
Step n = s.next();
// 如果下一个节点为空
if (n == null) {
break;
}
// 将下一步压栈
steps.add(n);
maze[n.row][n.col] = '*';
// 调用方法 如果有需要回溯
back();
//printMaze();
//如果无解则返回false
if (!solvable){
return false;
}
}
return true;
}
private void back() {
// TODO Auto-generated method stub
// 循环将
// 没有可走的步数从栈内弹出
while (!steps.getLast().hasMoreDir()) {
// 移除并返回最后一步
Step s = steps.removeLast();
maze[s.row][s.col] = ' ';
// 如果栈被弹空
// 说明已经遍历完成
// 返回无解
if (steps.size() == 0) {
this.solvable = false;
return;
}
}
}
public void printMaze() {
//打印迷宫
for (int i = 0; i < maze.length; i++) {
for (int j = 0; j < maze[i].length; j++) {
System.out.print(maze[i][j]);
}
System.out.println();
}
System.out.println("-----------------------------");
}
private class Step {
private int row;
private int col;
// 该点可以走的方向的栈
private LinkedList<int[]> dirs = new LinkedList<int[]>();
// 走步构造方法
// 在构造的时候
// 判断并且保存该点
// 可以走的方向
public Step(int row, int col) {
this.row = row;
this.col = col;
// 方向上判断
int drow = row + DIR_UP[1];
int dcol = col + DIR_UP[0];
if (drow >= 0 && dcol >= 0 && drow < maze.length
&& dcol < maze[0].length && maze[drow][dcol] == ' ') {
dirs.add(DIR_UP);
}
// 方向下判断
drow = row + DIR_DOWN[1];
dcol = col + DIR_DOWN[0];
if (drow >= 0 && dcol >= 0 && drow < maze.length
&& dcol < maze[0].length && maze[drow][dcol] == ' ') {
dirs.add(DIR_DOWN);
}
// 方向左判断
drow = row + DIR_LEFT[1];
dcol = col + DIR_LEFT[0];
if (drow >= 0 && dcol >= 0 && drow < maze.length
&& dcol < maze[0].length && maze[drow][dcol] == ' ') {
dirs.add(DIR_LEFT);
}
// 方向右判断
drow = row + DIR_RIGHT[1];
dcol = col + DIR_RIGHT[0];
if (drow >= 0 && dcol >= 0 && drow < maze.length
&& dcol < maze[0].length && maze[drow][dcol] == ' ') {
dirs.add(DIR_RIGHT);
}
}
// 返回是否还有可走的方向
public boolean hasMoreDir() {
return dirs.size() > 0;
}
// 返回下一步
public Step next() {
// 取出最近一个存进去的方向
int[] d = dirs.removeLast();
//计算先步的位置
int newRow = row + d[1];
int newCol = col + d[0];
// 判断新位置是否
// 走出迷宫
if (newRow == 0 || newCol == 0 || newRow == maze.length - 1
|| newCol == maze[0].length-1) {
maze[newRow][newCol] = 'X';
return null;
}
// 返回新步
return new Step(newRow, newCol);
}
}
//主方法
public static void main(String[] args) {
Maze maze=new Maze(new char[][]{
{'#',' ','#','#','#','#','#','#','#','#','#','#','#','#','#',},
{'#',' ','#','#','#','#',' ','#','#','#','#',' ',' ',' ','#',},
{'#',' ',' ',' ',' ',' ',' ',' ',' ','#','#',' ','#',' ','#',},
{'#',' ','#','#',' ','#','#','#',' ','#','#','#','#',' ','#',},
{'#',' ','#',' ',' ',' ',' ','#',' ',' ',' ',' ',' ',' ','#',},
{'#',' ','#','#','#','#','#','#','#','#','#','#','#','#','#',},
{'#',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#','#','#',},
{'#','#','#',' ','#','#','#','#','#','#','#',' ','#','#','#',},
{'#','#','#',' ',' ',' ',' ',' ',' ','#','#',' ','#','#','#',},
{'#','#','#',' ','#','#','#','#',' ','#','#','#','#','#','#',},
{'#','#','#',' ',' ',' ','#','#',' ',' ',' ',' ',' ',' ',' ',},
{'#','#','#',' ','#','#','#','#','#','#',' ','#','#',' ','#',},
{'#','#','#','#','#','#','#','#','#','#','#','#','#','#','#',}
},0,1);
//打印迷宫
maze.printMaze();
if (maze.solve()){
System.out.println("------------找到解----------");
maze.printMaze();
} else {
System.out.println("迷宫无解");
}
}
}