关于用深度优先算法生成迷宫与寻找路径的一些回忆

当老师教完类这一章,就给我们布置了几个实验,其中一个就是迷宫问题,属于其中最难的一个实验了,这一个实验也折腾我好几个礼拜,然而对于班上的几个大神,这个也就是个小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();
        }
     }
}

截图:(源代码已上传资源)




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值