用堆栈数据结构求解迷宫问题的方法

回溯法求解迷宫问题,使用了堆栈数据结构。

源码下载地址:使用DEV-C  5.11编译

使用堆栈数据结构解迷宫问题资源-CSDN文库

定义一个结构,用来存储迷宫的坐标数据

typedef struct 

 {

   int x; /* 行值 */

   int y; /* 列值 */

 }PosType;

规定迷宫的最大范围是25*25

#define MAXLENGTH 25

定义迷宫数据类型,就是整型二维数组,起个别名叫 MazeType

typedef  int  MazeType[MAXLENGTH][MAXLENGTH];

然后,给定迷宫尺寸,包括围墙,例如10*10,那么程序将生成一个空的围墙迷宫轮廓,用0表示墙,其它地方表示可通过,用1表示

//下面的语句是把迷宫围起来

   for(i=0;i<x;i++) /* 定义周边值为 0(同墙) */

   {

     m[0][i]=0;   /* 行周边 */

     m[x-1][i]=0;

   }

   for(j=1;j<y-1;j++)

   {

     m[j][0]=0; /* 列周边 */

     m[j][y-1]=0;

   }

   for(i=1;i<x-1;i++)

     for(j=1;j<y-1;j++)

       m[i][j]=1; /* 定义通道初值为1 */

此时迷宫中的数据如下:

四周是围墙,中间有数字1的部分是可以通过的部分。

x是行,y是列

坐标

0

1

2

3

4

5

6

7

8

9

0

0

0

0

0

0

0

0

0

0

0

1

0

1

1

1

1

1

1

1

1

0

2

0

1

1

1

1

1

1

1

1

0

3

0

1

1

1

1

1

1

1

1

0

4

0

1

1

1

1

1

1

1

1

0

5

0

1

1

1

1

1

1

1

1

0

6

0

1

1

1

1

1

1

1

1

0

7

0

1

1

1

1

1

1

1

1

0

8

0

1

1

1

1

1

1

1

1

0

9

0

0

0

0

0

0

0

0

0

0

接着程序要求提供迷宫中的墙的位置的数据,可以定义一个数组,用坐标说明墙的位置:

   PosType wall[18]={\

   {1,3},{1,7},{2,3},{2,7},{3,5},{3,6},\

   {4,2},{4,3},{4,4},{5,4},{6,2},{6,6},\

   {7,2},{7,3},{7,4},{7,6},{7,7},{8,1}\

   };

之后,程序生成这样的迷宫图,迷宫中值为0的地方就表示墙。值为1的地方是可以通过的地方。

   x是行,y是列

坐标

0

1

2

3

4

5

6

7

8

9

0

0

0

0

0

0

0

0

0

0

0

1

0

1

1

0

1

1

1

0

1

0

2

0

1

1

0

1

1

1

0

1

0

3

0

1

1

1

1

0

0

1

1

0

4

0

1

0

0

0

1

1

1

1

0

5

0

1

1

1

0

1

1

1

1

0

6

0

1

0

1

1

1

0

1

1

0

7

0

1

0

0

0

1

0

0

1

0

8

0

1

1

1

1

1

1

1

1

0

9

0

0

0

0

0

0

0

0

0

0

接着,程序要求给出起始位置坐标,这里是11,和终止位置坐标88

begin.x=1; begin.y=1;

end.x=8; end.y=8;

然后,程序开始探索迷宫,每进入一个坐标点位,都判断一下这里是否可以通过,也就是坐标点位上的值是否为1

if(Pass(curpos))

如果可以通过,坐标入栈,并在这一坐标处记录走过的步数。  

      FootPrint(curpos);   //在迷宫当前坐标处留下足迹,就是在迷宫单元中记录走到第几步了
       
       //下面的步骤将 e 堆栈元素压入堆栈 
       e.ord=curstep;         //记录足迹编号,就是走第几步了 
       e.seat.x=curpos.x;   //记录迷宫坐标 
       e.seat.y=curpos.y;  
       
       e.di=0;      //记录方向,0,1,2,3分别代表 东南西北 
       Push(&S,e);    //S是堆栈变量,e是堆栈元素

接着按东南西北的顺序试图走下一步,如果可以通过,还是坐标入栈,记录步数。

curpos=NextPos(curpos,e.di);

这个堆栈元素e.di就是用来记录方向的,规定东:0,南:1,西:2,北:3

如果不能通过,则进行弹栈操作,退回到上一可以通过的步子处,继续按照东南西北的顺序探索下一步。如此循环往复,直到走出迷宫。

         Pop(&S,&e);    /* 退栈到前一位置 */
         curstep--;
         while(e.di==3 && !StackEmpty(S))    /* 前一位置处于最后一个方向(北) */
         {
           MarkPrint(e.seat);   /* 留下不能通过的标记(-1) */
           Pop(&S,&e);            /* 退回一步 */
           curstep--;
         }
         if(e.di<3)     /* 没到最后一个方向(北) */
         {
           e.di++;     /* 换下一个方向探索 */
           Push(&S,e);
           curstep++;
           curpos=NextPos(e.seat,e.di);     /* 设定当前位置是该新方向上的相邻块 */
         }

还有一种情况是,当走到某一步时候,四个方向上都无法通过,这时,需要在这一坐标处标记-1,表示探索过,没有通路。

迷宫中的值有这几种情况:

a.可以通过的坐标点位用1表示

b.如果值>1,表示记录着步数,也就是这里已经走过了,

c.如果是0,表示这里是墙,

d.如果是-1,表示这里走过且不通。

最后得到的一条迷宫路径:-1表示走过,但是不通,又往回退的情况。

走迷宫过程的视频演示:

https://v.youku.com/v_show/id_XNjM5NzY4NjA5Ng==.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值