走迷宫问题
迷宫是许多小方格构成的矩形,如下图所示,在每个小方格中有的是墙(图 中的“1”)有的是路(图中的“0”)。走迷宫就是从一个小方格沿着上,下,左,右四个方向都临近的方格,当然不能穿墙。设迷宫的入口是在左上角(1,1),出口是在右下角(8,8)。根据给定的迷宫,找出一条从入口到出口的路径。
/**
*定义存放在队列里的数据类型
*x,y表示访问的二维表的坐标,pre表示前驱节点编号。
*/
class Struct {
int x, y, pre;
Struct(int x, int y, int pre) {
this.x = x;
this.y = y;
this.pre = pre;
}
}
public class Main {
/**
* 数组sq模拟一个队列
*/
static Struct sq[] = new Struct[100];
public static void main(String[] args) {
/**
* 数组maze存放迷宫二维表
*/
int maze[][] = {
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 1, 0 },
{ 0, 0, 0, 0, 1, 0, 1, 0 },
{ 0, 1, 0, 0, 0, 0, 1, 0 },
{ 0, 1, 0, 1, 1, 0, 1, 0 },
{ 0, 1, 0, 0, 0, 0, 1, 1 },
{ 0, 1, 0, 0, 1, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 0 }
};
/**
* 数组fx,fy组合使用表示可以搜索的上,下,左,右四个方向
*/
int fx[] = { 1, -1, 0, 0 };
int fy[] = { 0, 0, -1, 1 };
/**
* qh代表队列头
* qe代表队列尾
*/
int qh = 0;
int qe = 1;
int i,j;
/**
* 访问过的地图位置标记为-1避免重复访问
* 由于题中说是从左上角开始访问,
* 所以左上角一定能访问,并先访问。
*/
maze[0][0] = -1;
/**
* 第一个访问点入队列
*/
sq[1] = new Struct(1, 1, 0);
while (qh != qe) {//当队头不等于对尾,表示队列不空
qh++; //出对列
for (int k = 0; k < 4; k++) { //搜索四个方向
i = sq[qh].x + fx[k];
j = sq[qh].y + fy[k];
if (check(i, j, maze)) { //判断方向是否可达
/**
* 入队列
*/
qe++;
sq[qe] = new Struct(i, j, qh);
maze[i-1][j-1] = -1;
/**
* 判断出口
*/
if (sq[qe].x == 8 && sq[qe].y == 8) {
out1(qe);
System.out.println();
out2(qe);
return;
}
}
}
}
}
/**
* 判断i,j位置是否可行
* @param i 横坐标(1~8)
* @param j 纵坐标(1~8)
* @param maze 地图
* @return
*/
static boolean check(int i, int j,int maze[][]) {
if (i < 1 || i > 8 || j < 1 || j > 8) {
return false;
}
if (maze[i-1][j-1] == 1 || maze[i-1][j-1] == -1) {
return false;
}
return true;
}
/**
* 顺序输出
*/
static void out1(int qe){
if(sq[qe].pre!=0){
out1(sq[qe].pre);
System.out.print("--("+sq[qe].x+","+sq[qe].y+")");
}else{
System.out.print("("+sq[qe].x+","+sq[qe].y+")");
}
}
/**
* 逆序输出
*/
static void out2(int qe) {
System.out.print("(" + sq[qe].x + "," + sq[qe].y+")");
while (sq[qe].pre != 0) {
qe = sq[qe].pre;
System.out.print("--(" + sq[qe].x + "," + sq[qe].y + ")");
}
}
}