迷宫算法的递归实现

**建议在VC6.0下创建console工程编译**

源码如下:

#i nclude <stdio.h>

typedef enum{X=0,up,dn,rt,lt} tDir;  //搜索方向
//->tDir t; t=X;

typedef struct tagNode           //节点结构
{
  int tag;    /*0 1*/   
  tDir comeDir;/*for back*/
  int up,rt,dn,lt; //towards
  int back;
}Node;
//-〉结构定义用';'不是','

int m[10][10]={     //初始化通道数据
  {1,0,0,0,0,0,1,1,1,1},
  {0,0,1,0,1,0,0,1,1,1},
  {1,1,1,0,0,1,1,1,1,1},
  {1,1,1,1,0,1,0,0,1,1},
  {1,1,1,1,0,1,0,1,1,1},
  {1,1,1,1,0,0,0,1,1,1},
  {1,1,1,1,1,1,0,1,1,1},
  {1,1,1,1,1,1,0,1,1,1},
  {1,1,1,1,1,1,0,0,0,0},
  {1,1,1,1,1,1,1,1,1,1},
  };

  int ini=1,inj=0;   //入点
  int outi=8,outj=9; //出口
  int cnt=0;    //看find递归调用次数
  Node maze[10][10];


/////////////////////////////////
//类型:
//功能:初始化迷宫数据
//步骤:
////////////////////////////////
void initmaze(Node mz[][10])
{
 int i,j;
 for(i=0;i<10;i++)
   for(j=0;j<10;j++)
   {
    mz[i][j].tag=m[i][j];
          mz[i][j].comeDir=X;
    mz[i][j].up=0;
    mz[i][j].dn=0;
    mz[i][j].rt=0;
    mz[i][j].lt=0;
    mz[i][j].back=0;
   }
}

/////////////////////////////////
//类型:
//功能:判断点是否在路径上
//步骤:
////////////////////////////////
int onway(Node nd)
{
 if(nd.tag!=0) return 0; //墙

 if(nd.up==0&&nd.dn==0&&nd.rt==0&&nd.lt==0) return 0; //没访问过
 
 if(nd.up==1&&nd.dn==1&&nd.rt==1&&nd.lt==1&&nd.back==1) return 0; //访问过但不通

 return 1;
}

/////////////////////////////////
//类型:
//功能:打印
//步骤:
////////////////////////////////
void print(Node mz[][10])
{   
 int i,j;
 
 printf("/n----------------/n");
 
 for(i=0;i<10;i++)
 { //一行
   for(j=0;j<10;j++)
   {
    if(onway(mz[i][j]))
      printf("@");
    else
      printf("%d",mz[i][j].tag);
   }
   printf("/n");
 }

 printf("-----------------/n");
}

/////////////////////////////////
//类型:递归函数
//功能:搜索路径
//步骤:
/*
  if 当前节点是出口 then return 1;

  if   不是是回退到本节点
  then 记录来的方向  返回根据来的方向设定其相对方向已走

  if 向N方向没走&&可以走 则向N递归走
  if 向E方向没走&&可以走 则向E递归走
  if 向S方向没走&&可以走 则向S递归走
  if 向W方向没走&&可以走 则向W递归走

  if 四个方向都走完了还没有结果
     if 是入口 return 0
  else 则回退
*/  
/////////////////////////////////
int find(Node mz[][10],int i,int j,tDir dir)
{
 
  cnt++;
  /////////////////////////////////
  //if 当前节点是出口 then return 1;
  if(i==outi&&j==outj) return 1;
 
  ///////////////////////////////// 
  //if   不是是回退到本节点
  //then 记录来的方向  根据来的方向设定其相对方向已走
  if(dir!=X)
  {
   mz[i][j].comeDir=dir;
   if(dir==up) mz[i][j].dn=1;
   if(dir==dn) mz[i][j].up=1;
   if(dir==rt) mz[i][j].lt=1;
   if(dir==lt) mz[i][j].rt=1;
  }

  int ni,nj;
  /////////////////////////////////////
  //if 向up方向没走&&不越界&&可以走 则向up递归走  
  //if 向dn方向没走&&不越界&&可以走 则向dn递归走
  //if 向rt方向没走&&不越界&&可以走 则向rt递归走
  //if 向lt方向没走&&不越界&&可以走 则向lt递归走
 
  if(mz[i][j].up==0)  //11111111111111
  {  
   mz[i][j].up=1;
     
   ni=i-1;
   nj=j;
     
   if(ni>=0&&mz[ni][nj].tag==0)
     if(find(maze,ni,nj,up)) return 1;
  }
  if(mz[i][j].dn==0)//222222222222222
  {  
   mz[i][j].dn=1;
     
   ni=i+1;
   nj=j;
     
   if(ni<10&&mz[ni][nj].tag==0)
     if(find(maze,ni,nj,dn)) return 1;
  }
  if(mz[i][j].rt==0)//333333333333333
  {  
   mz[i][j].rt=1;
     
   ni=i;
   nj=j+1;
     
   if(nj<10&&mz[ni][nj].tag==0)
      if(find(maze,ni,nj,rt)) return 1;//find(maze,ni,nj,rt);
  }
  if(mz[i][j].lt==0)//44444444444444444
  {  
   mz[i][j].lt=1;
     
   ni=i;
   nj=j-1;
     
   if(nj>=0&&mz[ni][nj].tag==0)
     if(find(maze,ni,nj,lt)) return 1;//find(maze,ni,nj,lt);
  }
  /////////////////////////////////////
  //四个方向都走完了还没有结果
  //   if 是入口 return 0
  //   else 则回退
  if(i==ini&&j==inj) return 0;
  else
  {
   mz[i][j].back=1;
   if(mz[i][j].comeDir=up)
   {
    ni=i+1;nj=j;
    if(find(maze,ni,nj,X)) return 1;
   }
   if(mz[i][j].comeDir=dn)
   {
    ni=i-1;nj=j;
    if(find(maze,ni,nj,X)) return 1;
   }
   if(mz[i][j].comeDir=rt)
   {
    ni=i;nj=j-1;
    if(find(maze,ni,nj,X)) return 1;
   }
   if(mz[i][j].comeDir=lt)
   {
    ni=i+1;nj=j+1;
    if(find(maze,ni,nj,X)) return 1;
   }
  }

  return 0;

}

////////////////////////////
//功能:主函数
//
///////////////////////////
void main()
{
  initmaze(maze);
  print(maze);
  getchar();

  if (find(maze,ini,inj,rt))
     print(maze);
  else
     printf("no way!");


  textcolor();
  printf("/ncnt=%d/n",cnt);
  getchar();
}

///////////////////////////////
//------心得----------------
//结构与枚举的使用
//数组传参数
//迷宫的算法
//有返回值递归函数的写法---每一条路径都要返回值

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值