迷宫递归算法

    一直对栈的用作回溯处理这些用法不熟悉,所以迷宫用栈的深度搜索一直都没写出来,今天又看看了严老师的数据结构,参考了上面的算法,把迷宫递归和用栈回溯都写了下,用的是类C语言,代码显得有些冗杂

    先是用递归写出来的,关键部分注释了下:

    

********************************************************************
      purpose:    迷宫递归算法
   maze[][]是迷宫的二维图,path[]是记录路径的数组
   point 是自定义结构体,有x、y表示坐标
********************************************************************
*/


void  maze_path( int  maze[][ 5 ], int  path[],point start,point des, int  length)                        
{
    
int i;
    
bool flag=false;
    
if(start.x==des.x&&start.y==des.y)                            //如果是目的点
    {
        
for (i=1;i<length;i++)
            printf(
"%d->",path[i]);
        printf(
"%d 查找完毕 ",(start.x-1)*3+start.y);
    }

    
else
    
{
        maze[start.x][start.y]
=1;
        path[length]
=(start.x-1)*3+start.y;         /*maze是个5*5的数组,由于外面要包一层墙,所以核心数组是个3*3的迷宫图,分别以1~9标号,映射方程为location=(x-1)*3+y    */
        
        
for(i=0;i<4;i++)
        
{
            
int next_x=start.x+dir[i][0];
            
int next_y=start.y+dir[i][1];
            
if(!maze[next_x][next_y])
            
{
                flag
=true;
                point temp;
                temp.x
=next_x;
                temp.y
=next_y;
                maze_path(maze,path,temp,des,
++length);
            }

        }

        
if(flag)
            
return;           *这一句自认为最重要,表示当前路径搜索不出通路,则中断该搜索分支,可以用笔在纸上单步模拟下,原理就清楚了*/              
    }

}

      失败之处在于没有用C++,感觉有些代码为了追求易读性,反而看上去冗杂了许多。比如point,最初为了程序更加直观,最后反而写出来更加不通读了。所以在写利用栈的迷宫算法代码时,没有用point,感觉也比较麻烦,先把算法的汉语贴出来,再来看看代码就很容易理解了:

 

设定当前位置的初值为入口位置; 
  
do {
    若当前位置可通, 
    则
{
     将当前位置插入栈顶;       
// 纳入路径 
     若该位置是出口位置,则算法结束; 
      
// 此时栈中存放的是一条从入口位置到出口位置的路径
     否则切换当前位置的东邻方块为新的当前位置; 
     }

    否则
    
{
    若栈不空且栈顶位置尚有其他方向未被探索, 
    则设定新的当前位置为: 沿顺时针方向旋转找到的栈顶位置的下一相邻块;
    若栈不空但栈顶位置的四周均不可通, 
    则
{ 删去栈顶位置;         // 从路径中删去该通道块
      若栈不空,则重新测试新的栈顶位置, 
      直至找到一个可通的相邻块或出栈至栈空; 
     }
 
   }
 
  }
  while  (栈不空); 

 

   我的代码基本上参考上面伪代码,中有几个需说明下:

   1. 加入了一个布尔值FindFlag,主要为了辨别是否已找到出口

   2. 仍然参考了上面的坐标映射,计算公式仍是 location=(x-1)*3+y

int  dir[ 4 ][ 2 ] = {{1,0},{0,1},{-1,0},{0,-1}} ;            // 方向的控制,很多参考书都是采用这方法,感觉不错

int  MazeFind( int  maze[][ 5 ], int  startX, int  startY, int  desX, int  desY)
{
    
bool FindFlag=false;
    stack MazeStack;
    initStack(MazeStack);
    
do
    
{
        
if(!maze[startX][startY])
        
{
            push(MazeStack,(startX
-1)*3+startY);
            
if (startX==desX&&startY==desY)
                FindFlag
=true;
            
else
            
{
                
int direction=maze[startX][startY]++;
                startX
=startX+dir[direction][0];
                startY
=startY+dir[direction][1];
            }

        }

        
else
        
{
            startX
=MazeStack.array[MazeStack.top]/3+1;
            startY
=MazeStack.array[MazeStack.top]%3;
            
if(!empty(MazeStack)&&maze[startX][startY]<4)
            
{
                
int direction=maze[startX][startY]++;
                startX
=startX+dir[direction][0];
                startY
=startY+dir[direction][1];
            }

            
if(!empty(MazeStack)&&maze[startX][startY]>=4)
            
{
                
int location=pop(MazeStack);
                startX
=location/3+1;
                startY
=location%3;
            }

        }

    }
 while(!empty(MazeStack)&&!FindFlag);
    
if (empty(MazeStack))
        
return 0;
    
else
    
{
        
for(int i=0;i<MazeStack.top;i++)
            printf(
"%d->",MazeStack.array[i]);
        printf(
"%d",MazeStack.array[i]);
        printf(
" ");
        
return 1;
    }

}
 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值