当老师教完类这一章,就给我们布置了几个实验,其中一个就是迷宫问题,属于其中最难的一个实验了,这一个实验也折腾我好几个礼拜,然而对于班上的几个大神,这个也就是个小case了,对于菜鸟的我,花了我好几个礼拜,也终于在最近给完成了。
为了生成一个迷宫,当然用数组表示是最好的了,我是基于深度优先算法用栈生成一个迷宫数组,深度优先的基本思想就是把初始点给标记为已访问并入栈,然后寻找该点的邻居节点,如果它的邻居节点没有访问过并且存在,就把邻居节点入栈并标记为已访问,当存在邻居节点时,就一直执行上面的步骤,当不存在未访问的邻居节点时,就出栈一个节点,并以当前栈顶元素继续访问它的未访问过的邻居节点,执行前面相同的步骤。它的终止条件就是栈为空时,也就访问完了所有节点。为了生成一个迷宫数组,需要注意几点,一是迷宫有墙,这就需要在访问邻居节点时中间的隔一个元素当作墙。二是要随机生成一个方向来访问,这样每次生成的迷宫就不一样了。三是随机访问一个方向时,最好标记该方向已访问过。至于寻找路径也是相同的思想。下面是主要的代码:(还望各位大神不吝赐教)
private int [][]map;//地图数组
private Stack<Point> sp;//用于生成迷宫时的栈
private int size;//迷宫尺寸
private Random rand;
private int der;//方向
//判断该点是否存在并访问过
public boolean isVisted(int x,int y){
if((x>0 && x<size) && (y>0 && y<size) && map[x][y]==0)
return false;
return true;
}
//深度优先遍历整个地图产生随机迷宫
public void DFScreateMap()
{
map[1][1]=1;//初始点
sp.push(new Point(1,1));//将当前点压入栈中
boolean []b={false,false,false,false};//标记某方向是否走过
int n=0;//标记某方向是否有未访问节点
while(!sp.isEmpty()){
der=rand.nextInt(4);
n=0;
if(der==0){//up
if(!isVisted(sp.peek().x-2, sp.peek().y)){
//标记该点的邻居节点,打开之间的墙,并把邻居节点压入栈中
map[sp.peek().x-1][sp.peek().y]=1;
map[sp.peek().x-2][sp.peek().y]=1;
sp.push(new Point(sp.peek().x-2,sp.peek().y));
n++;
}
b[0]=true;//标记该方向已走过
}
else if(der==1){//down
if(!isVisted(sp.peek().x+2, sp.peek().y)){
map[sp.peek().x+1][sp.peek().y]=1;
map[sp.peek().x+2][sp.peek().y]=1;
sp.push(new Point(sp.peek().x+2,sp.peek().y));
n++;
}
b[1]=true;
}
else if(der==2){//left
if(!isVisted(sp.peek().x, sp.peek().y-2)){
map[sp.peek().x][sp.peek().y-1]=1;
map[sp.peek().x][sp.peek().y-2]=1;
sp.push(new Point(sp.peek().x,sp.peek().y-2));
n++;
}
b[2]=true;
}
else if(der==3){//right
if(!isVisted(sp.peek().x, sp.peek().y+2)){
map[sp.peek().x][sp.peek().y+1]=1;
map[sp.peek().x][sp.peek().y+2]=1;
sp.push(new Point(sp.peek().x,sp.peek().y+2));
n++;
}
b[3]=true;
}
if(n==0){
if(b[0]&&b[1]&&b[2]&&b[3]){//如果四个方向都走过且没有未访问的节点,则退回上一个节点
sp.pop();
b[0]=b[1]=b[2]=b[3]=false;
}
}
else b[0]=b[1]=b[2]=b[3]=false;
}
private Stack<Point> sw;//用于寻找路径时的栈
//DFS算法寻找路径
public void DFSsearchWay(int array[][], int size){
sw.push(new Point(1,1));
array[1][1]=3;
while(!sw.isEmpty() && (sw.peek().x!=size-2 || sw.peek().y!=size-2)){
if(array[sw.peek().x][sw.peek().y+1]==1){ //right
sw.push(new Point(sw.peek().x,sw.peek().y+1));
array[sw.peek().x][sw.peek().y]=3;
}
else if(array[sw.peek().x+1][sw.peek().y]==1){ //down
sw.push(new Point(sw.peek().x+1,sw.peek().y));
array[sw.peek().x][sw.peek().y]=3;
}
else if(array[sw.peek().x-1][sw.peek().y]==1){ //up
sw.push(new Point(sw.peek().x-1,sw.peek().y));
array[sw.peek().x][sw.peek().y]=3;
}
else if(array[sw.peek().x][sw.peek().y-1]==1){ //left
sw.push(new Point(sw.peek().x,sw.peek().y-1));
array[sw.peek().x][sw.peek().y]=3;
}
else{
array[sw.peek().x][sw.peek().y]=2;
sw.pop();
}
}
}
截图:(源代码已上传资源)