数据结构课程设计——迷宫问题课程设计报告

上学时没学过数据结构和算法,于是现在有机会就自学。下面是我最近在等待进入项目组期间,花了1小时学习了一下迷宫问题。下面是我学习时找到的一篇课程设计的报告,然后自己先看懂,然后又在VC6.0下运行了。

迷宫问题

一.需求设计:以一个m*m 的方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口的通道,或得出没有通路的结论。

二.概要设计:

存储结构:

采用了数组以及结构体来存储数据,在探索迷宫的过程中用到的栈,属于顺序存储结构。

/*八个方向的数组表示形式*/

   int move[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1, 0},{-1, 1}};

   /*用结构体表示位置*/

   struct position

   {

      int x,y;

   };

   position stack[m*m+1];

基本算法:

走迷宫的过程可以模拟为一个搜索的过程:每到一处,总让它按东、东南、南、西南、西、西北、北、东北8个方向顺序试探下一个位置;如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;如果8个方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。

每前进或后退一步,都要进行判断:若前进到了出口处,则说明找到了一条通路;若退回到了入口处,则说明不存在通路。

用一个字符类型的二维数组表示迷宫,数组中每个元素取值“0”(表示通路)或“1”(表示墙壁)。迷宫的入口点在位置(1,1)处,出口点在位置(m,m)处。设计一个模拟走迷宫的算法,为其寻找一条从入口点到出口点的通路。

二维数组的第0行、第m+1行、第0列、第m+1列元素全置成“1”,表示迷宫的边界;第1行第1列元素和第m行第m列元素置成“0”,表示迷宫的入口和出口;其余元素值用随机函数产生。

假设当前所在位置是(x,y)。沿某个方向前进一步,它可能到达的位置最多有8个。

如果用二维数组move记录8个方向上行下标增量和列下标增量,则沿第i个方向前进一步,可能到达的新位置坐标可利用move数组确定:

        x=x+move[i][0]

        y=y+move[i][1]

从迷宫的入口位置开始,沿图示方向顺序依次进行搜索。在搜索过程中,每前进一步,在所到位置处做标记“”(表示这个位置在通路上),并将该位置的坐标压入栈中。每次后退的时候,先将当前所在位置处的通路标记“”改成死路标记“×”(表示这个位置曾到达过但走不通,以后不要重复进入),然后将该位置的坐标从栈顶弹出。搜索到出口位置时,数组中那些值为“”的元素形成一条通路。

三.详细设计:

源程序:

 

/*

   迷宫问题

   走迷宫的过程可以模拟为一个搜索的过程:每到一

处,总让它按东、东南、南、西南、西、西北、北、东北

个方向顺序试探下一个位置;如果某方向可以通过,并且不

曾到达,则前进一步,在新位置上继续进行搜索;如果个

方向都走不通或曾经到达过,则退回一步,在原来的位置上

继续试探下一位置。

    每前进或后退一步,都要进行判断:若前进到了出

口处,则说明找到了一条通路;若退回到了入口处,则说明

不存在通路。

    用一个字符类型的二维数组表示迷宫,数组中每个元素

取值“0”(表示通路)或“1”(表示墙壁)。迷宫的入口点在

位置(1,1)处,出口点在位置(m,m)处。这个算法,为

其寻找一条从入口点到出口点的通路。

*/

#include<stdio.h>

#include<iostream>

#include<stdlib.h>

#include<time.h>

 

int main(void)

{

   int m=1;

   while (m!=0)

   {

#if 0

      /* 数组不支持动态的定义 */

      printf("输入m,使得为m*m的方阵迷宫(m>0 输入0 时退出:)\n");

      scanf ("%d",&m);

#endif

      m = 8;

      printf("迷宫矩阵的大小为:%d * %d\n", m, m);

 

      /*设定n*n的方阵迷宫*/

      /*数组的形式表示八个方向*/

      int move[8][2]={{0,1},{1,1},{1,0},

                {1,-1},{0,-1},{-1,-1},{-1, 0},{-1, 1}};

   

      /*用结构体表示位置*/

      struct position

      {

         int x;

         int y;

      };

 

      /*用于记录和输出迷宫探路中相关符号,包括1 .*/

      char maze[10][10];

 

      /*用栈来存储探路过程中的数据*/

      position stack[64+1];

      int top;/*栈顶*/

      int i,x,y,ok;

      position p;

 

      /*二维数组的第0行、第m+1行、第0列、第m+1列元素全

      置成"1",表示迷宫的边界;第1行第1列元素和第m行第m列

      元素置成"0",表示迷宫的入口和出口;其余元素值用随机

      函数产生。*/

      srand(time(0));  /* 产生一个随机种子 */

      for(x=1;x<=m;x++)

         for(y=1;y<=m;y++)

            maze[x][y]=48+rand()%2;

 

      maze[1][1]='0';maze[m][m]='0';     /* 入口 */

 

      for(x=0;x<=m+1;x++)

      {

         maze[x][0]='1';maze[x][m+1]='1';  /* 边界 */

      }

 

      for(y=0;y<=m+1;y++)

      {

         maze[0][y]='1';maze[m+1][y]='1';  /* 边界 */

      }

 

      p.x=1;p.y=1;

      top=1;stack[top]=p;

      maze[1][1]='.';

 

      /*开始探路

         走迷宫的过程可以模拟为一个搜索的过程:每到一

      处,总让它按东、东南、南、西南、西、西北、北、东北

      个方向顺序试探下一个位置;如果某方向可以通过,并且不

      曾到达,则前进一步,在新位置上继续进行搜索;如果个

      方向都走不通或曾经到达过,则退回一步,在原来的位置上

      继续试探下一位置。

         每前进或后退一步,都要进行判断:若前进到了出

      口处,则说明找到了一条通路;若退回到了入口处,则说明

      不存在通路。*/

      do{

         p=stack[top];

         ok=0;i=0;

         while((ok==0)&&(i<8))

         {

            x=p.x+move[i][0];

            y=p.y+move[i][1];

            if(maze[x][y]=='0')

            {

                p.x=x;p.y=y;

                stack[++top]=p;

                maze[x][y]='.';

                ok=1;

            }

            i++;

         }

         if(i==8)

         {

            maze[p.x][p.y]='*';

            top--;

         }

      } while((top>0)&&((p.x!=m)||(p.y!=m)));

 

      /*输出探路结果*/

      if(top==0)

      {

         printf("没有路径\n");

      }

      else 

      {

         printf("有路径\n");

      }

 

      /*输出探路迷宫留下的踪迹*/

#if 0

      for(x=1;x<=m;x++)

      {

         printf("\n");

         for(y=1;y<=m;y++) 

            printf("%c ",maze[x][y]);

      }

#else

      /*输出整个迷宫*/

      for(x=0; x <= m + 1; x++)

      {

         printf("\n");

         for(y=0;y<=m+1;y++) 

            printf("%c ",maze[x][y]);

      }

#endif

      printf("\n");

 

      system("pause"); 

 

   }

 

   return 0;

}


四.调试分析:

测试数据和结果:

有路径的情况,

无路径的情况,

算法时间复杂度:

         O(m²)

对相关问题的思考:

       这个迷宫问题的算法中,要在开始设置迷宫的大小。在探索迷宫路线的过程中,是通过不断的尝试来得到最终的结果,由于不能对已经设定为可走路径进行返回,所以在这个算法中有时候可能不能得到走出迷宫的路径。如下:

 

原文来自: http://wenku.baidu.com/view/43040e73f242336c1eb95e29.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值