数据结构(C语言版)实验报告(迷宫)

时间:2024.4.27

《数据结构与算法》实验报告

评分依据及结果

一、         需求分析

1.问题描述:

以一个m*n的长方阵表示迷宫,空格和感叹号分别表示迷宫中的通路和障碍。设计一个程序,对随机产生的迷宫,求一条从入口到出口的通路,或得出没有通路的结论。

2.基本要求

  首先实现一个以链表为存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(ijd)的形式输出。

其中(ij)表示迷宫的一个坐标,d表示走到下一座标的方向。

3.程序的执行命令有:

1)输入迷宫的列数   2)输入迷宫的行数

二、         概要设计

为实现上述功能,需要以一个链表为存储结构的栈类型

1.     栈的顺序存储表示

typedef struct

{  

   int x;  /*列*/  

   int y;  /*行*/ 

}PosType;   //坐标位置类型   

typedef struct

{  

   int ord;   //通道块在路径上的"序号"   

   PosType seat;  //通道块在迷宫中的"坐标位置"   

   int di;    //从此通道块走向下一通道块的"方向" 

}SElemType;   //栈的元素类型  

typedef struct

{     

   SElemType *base; 

   SElemType *top;   

   int stacksize;           //当前已分配的存储空间,以元素为单位 

}

SqStack;

//迷宫程序

typedef struct

{   

   int lie;     /*列数*/    

   int hang;  /*行数*/   

   char a[999][999];

}

MazeType;     /*迷宫类型*/      

2.       基本操作

int  InitStack(SqStack *S)//分配空间

int GetTop(SqStack *S,SElemType *e) //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR

int Push(SqStack *S,SElemType *e)//插入元素e作为新的栈顶元素

int Pop(SqStack *S,SElemType *e) //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

int generatemaze( MazeType *maze)// 随机生成迷宫

int Pass(MazeType *maze, PosType curpos )  //判断当前位置可否通过

int FootPrint(MazeType *maze,PosType curpos) //留下足迹

int MarkPrint(MazeType *maze,PosType curpos) //留下不能通过的标记

PosType NextPos(PosType curpos,int di) //返回当前位置的下一位置

int  MazePath(MazeType *maze,PosType start,PosType end) //若迷宫有解,则求得一条存放在栈中(从栈底到栈顶),并返回OK,否则返回ERROR

void  PrintMaze(MazeType *maze)         //打印迷宫 

三、         详细设计

//程序的头文件

#include <stdio.h>

#include <malloc.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

//函数的返回值

#define  OK      1

#define  ERROR   0

#define  NULL    0 

#define  OVERFLOW    -2  

#define STACK_INIT_SIZE 100

#define STACKINCREMENT  10 

//栈的顺序存储表示

typedef struct

{  

         int x;  /*列*/  

         int y;  /*行*/ 

}PosType;   //坐标位置类型   

typedef struct

{  

         int ord;   //通道块在路径上的"序号"   

         PosType seat;  //通道块在迷宫中的"坐标位置"   

         int di;    //从此通道块走向下一通道块的"方向" 

}SElemType;   //栈的元素类型  

typedef struct

{     

         SElemType *base; 

         SElemType *top;   

         int stacksize;           //当前已分配的存储空间,以元素为单位 

}

SqStack;   

//基本操作

int  InitStack(SqStack *S)

{    

         S->base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));   

         if(!S->base)  

                   exit(OVERFLOW);   

         S->top=S->base;    

         S->stacksize=STACK_INIT_SIZE;   

         return OK;

//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR

int GetTop(SqStack *S,SElemType *e)

{    

         if(S->top==S->base)

                   return ERROR;   

         *e=*(S->top-1);

         return OK; 

}  

int Push(SqStack *S,SElemType *e)//插入元素e作为新的栈顶元素

{    

         if(S->top-S->base>=S->stacksize)/*栈满,追加存储空间*/   

         {  

                   S->base=(SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));    

                   if(!S->base)

                            exit(OVERFLOW); 

                   S->top=S->base+S->stacksize;  

                   S->stacksize+=STACKINCREMENT;    

}    

         *S->top++=*e;   

         return OK;

//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

int Pop(SqStack *S,SElemType *e)

{    

         if(S->top==S->base) 

                   return ERROR;   

         *e=*--S->top;   

         return OK;

}  

int StackEmpty(SqStack *S)

{    

         return(S->top==S->base) 

;}  

//迷宫程序

typedef struct

{   

         int lie;     /*列数*/    

         int hang;  /*行数*/   

         char a[999][999];

}

MazeType;     /*迷宫类型*/   

/*随机生成迷宫*/ 

int generatemaze( MazeType *maze)

         int i,j;  

         maze->a[0][0]=2;   

         maze->a[++maze->hang][++maze->lie]=3;   /*设置外墙*/   

         maze->a[0][maze->lie]='!'; 

         maze->a[maze->hang][0]='!';  

         for(j=1;j<maze->lie;j++)   

         {

                   maze->a[0][j]='!';

                   maze->a[maze->hang][j]='!';

         } 

         for(i=1;i<maze->hang;i++)    

         {

                   maze->a[i][0]='!';

                   maze->a[i][maze->lie]='!';

         } 

         srand((unsigned)time( NULL ));  

         rand();     

         for(i=1; i <maze->hang; i++)    

                   for(j=1;j<maze->lie;j++)   

                   {   

                            if (rand()>=RAND_MAX/4) maze->a[i][j] =' ';   //' ' 暗示出路    

                            else maze->a[i][j] ='!';                    //'!'暗示无出路    

                   }  

                   return OK; 

}

int Pass(MazeType *maze, PosType curpos )  //判断当前位置可否通过

         if ((curpos.x < 1) || (curpos.x >= maze->lie))

                   return ERROR; 

         if ((curpos.y < 1) || (curpos.y >= maze->hang))

                   return ERROR;  

         if (maze->a[curpos.y][curpos.x]==' ')

                   return OK;      

         else    return ERROR;

}  

int FootPrint(MazeType *maze,PosType curpos) //留下足迹

{     

         maze->a[curpos.y][curpos.x]='*';    

         return OK;

}  

int MarkPrint(MazeType *maze,PosType curpos) //留下不能通过的标记

{    

         maze->a[curpos.y][curpos.x]='@';   

         return OK;

}

PosType NextPos(PosType curpos,int di)

//返回当前位置的下一位置

{

         PosType pos=curpos;

         switch(di)

         {

         case 1: //右东

                   pos.x++;

                   break;

         case 2:  //下南     

                   pos.y++;    

                   break;   

         case 3:  //左西       

                   pos.x--;    

                   break;   

         case 4:  //上北     

                   pos.y--;     

                   break;    

}    

         return  pos;

}  

//若迷宫有解,则求得一条存放在栈中(从栈底到栈顶),并返回OK,否则返回ERROR

int  MazePath(MazeType *maze,PosType start,PosType end)

{    

         PosType curpos;     

         SqStack *S=(SqStack *)malloc(sizeof(SqStack));   

         InitStack(S);   

         SElemType *e;    

         e=(SElemType *)malloc(sizeof(SElemType));   

         curpos=start;    //设定当前位置为入口位置   

         int curstep = 1;    //探索第一步

         do    {       

                   if(Pass(maze,curpos))  //当前位置可通过    

                   {              

                            FootPrint(maze,curpos);          

                            e->ord=curstep;    

                            e->seat=curpos;    

                            e->di=1;    

                            Push(S,e);

                            if(curpos.x==end.x&&curpos.y==end.y) 

                                     return (OK);     

                            curpos=NextPos(curpos,1);     

                            curstep++;   

                   }   

                   else    

                   {        

                            if(!StackEmpty(S))    

                            {          

                                     Pop(S,e);              

                                     while(e->di==4&&!StackEmpty(S))   //栈不空但栈顶位置四周均不通     

                                     {        

                                               MarkPrint(maze,e->seat); 

                                               Pop(S,e);     

                                     }     

                                     if(e->di<4)           //栈不空且栈顶位置四周有其他位置未探索    

                                     {        

                                               e->di++;       

                                               Push(S,e);                 

                                               curpos=e->seat;                 

                                               curpos=NextPos(curpos,e->di);    

                                     }     

                            }     

                   }    

         }

         while(!StackEmpty(S));

         return ERROR;

}  

void  PrintMaze(MazeType *maze)         //打印迷宫 

{    

         int i,j,k,n;   

         int c[999],d[999];

         for(i=0,k=0;i<=maze->hang;i++) 

         {  

                   for(j=0;j<=maze->lie;j++)

                   {   

                            printf("%c ",maze->a[i][j]);   

                            if(maze->a[i][j]=='*')   

                            {    

                                     c[k]=i;    

                                     d[k]=j;    

                                     k++;

                            }

                   }         

                   printf("\n"); 

         }

         n=k;          

         for(k=0;k<n;k++)

         printf("<%d,%d>",c[k],d[k]);

         printf("\n");       

         printf("\n");

}

int main()

{

         int zmg;   

         char ch;    

         printf("                  数据结构课程设计--迷宫问题求解     \n\n");    

         printf("             |----------------------------------------|\n");    

         printf("             |                                        |\n");    

         printf("             |                                        |\n");   

         printf("             |                                        |\n");   

         printf("             |                                        |\n");   

         printf("             |          XXXX    XXXXXXXXXXXXXX   |\n");    

         printf("             |                 XXXXXXX                |\n");    

         printf("             |----------------------------------------|\n");     

         getchar();    

         do   

         {     

                   system("cls");   

                   fflush(stdin);      

                   MazeType *maze=(MazeType *)malloc(sizeof(MazeType));      //设置迷宫的长宽不含外墙    

                   printf("请输入迷宫的列数(不含外墙时):");   

                   scanf("%d",&maze->lie);    

                   printf("请输入迷宫的行数(不含外墙时):");

                   scanf("%d",&maze->hang);   

                   generatemaze(maze);   

                   printf("随机创建迷宫\n");   

                   PrintMaze(maze);   

                   getchar();   

                   getchar();    

                   PosType start,end;    

                   start.x=1;start.y=1;    

                   end.x=maze->lie-1;end.y=maze->hang-1;   

                   zmg=MazePath(maze,start,end);   

                   if(zmg)       

                   {    

                            printf("此迷宫通路为\n");     

                            PrintMaze(maze);    

                   }    

                   else 

                            printf("此迷宫无通路\n");    //getchar();    

                   printf("再次尝试?(Y/N)?");

                   scanf("%c",&ch);

         }

         while(ch=='Y'||ch=='y');    

         return 0;

}

四、         调试分析

1.       本程序界面设计合理,以空格为通路,感叹号!为障碍 ,笑脸为起始点,*为行走路线,心形为出口

设计精巧,便于用户使用。

  2. 获得用户输入时一步一步的提示用户输入,具有很强的实用性。

  3. 本实习作业采用数据抽象的程序设计方法,使得设计思路清晰,实现时调试顺利。

五、         用户守则

 1.本程序的运行环境为windows操作系统,可执行文件为:a.exe

 2.为了界面更加友好特将背景颜色设计为黑色,字体为白色。

 3.进入演示程序后即显示文本形式的用户界面:

按回车键,即可进行迷宫求解

六、         测试结果

七、         附录(源代码)

#include <stdio.h>

#include <malloc.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#define  OK      1

#define  ERROR   0

#define  NULL    0 

#define  OVERFLOW    -2  

#define STACK_INIT_SIZE 100

#define STACKINCREMENT  10  

//栈的顺序存储表示

typedef struct

{  

     int x;  /**/  

     int y;  /**/ 

}PosType;   //坐标位置类型   

typedef struct

{  

     int ord;   //通道块在路径上的"序号"   

     PosType seat;  //通道块在迷宫中的"坐标位置"   

     int di;    //从此通道块走向下一通道块的"方向

}SElemType;   //栈的元素类型  

typedef struct

{     

     SElemType *base; 

     SElemType *top;   

     int stacksize;           //当前已分配的存储空间,以元素为单位 

}

SqStack;   

//基本操作

int  InitStack(SqStack *S)

{    

     S->base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));   

     if(!S->base)  

            exit(OVERFLOW);   

     S->top=S->base;    

     S->stacksize=STACK_INIT_SIZE;   

     return OK;

//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR

int GetTop(SqStack *S,SElemType *e)

{    

     if(S->top==S->base)

            return ERROR;   

     *e=*(S->top-1);

     return OK; 

}  

int Push(SqStack *S,SElemType *e)//插入元素e作为新的栈顶元素

{    

     if(S->top-S->base>=S->stacksize)/*栈满,追加存储空间*/   

     {  

     S->base=(SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));    

            if(!S->base)

                   exit(OVERFLOW); 

            S->top=S->base+S->stacksize;  

            S->stacksize+=STACKINCREMENT;    

}    

     *S->top++=*e;   

     return OK;

//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

int Pop(SqStack *S,SElemType *e)

{    

     if(S->top==S->base) 

            return ERROR;   

     *e=*--S->top;   

     return OK;

}  

int StackEmpty(SqStack *S)

{    

     return(S->top==S->base) 

;}  

//迷宫程序

typedef struct

{   

     int lie;     /*列数*/    

     int hang;  /*行数*/   

     char a[999][999];

}

MazeType;     /*迷宫类型*/   

/*随机生成迷宫*/ 

int generatemaze( MazeType *maze)

     int i,j;  

     maze->a[0][0]=2;   

     maze->a[++maze->hang][++maze->lie]=3;   /*设置外墙*/   

     maze->a[0][maze->lie]='!'; 

     maze->a[maze->hang][0]='!';  

     for(j=1;j<maze->lie;j++)   

     {

            maze->a[0][j]='!';

            maze->a[maze->hang][j]='!';

     } 

     for(i=1;i<maze->hang;i++)    

     {

            maze->a[i][0]='!';

            maze->a[i][maze->lie]='!';

     } 

     srand((unsigned)time( NULL ));  

     rand();     

     for(i=1; i <maze->hang; i++)    

            for(j=1;j<maze->lie;j++)   

            {   

                   if (rand()>=RAND_MAX/4) maze->a[i][j] =' ';   //' ' 暗示出路    

                   else maze->a[i][j] ='!';                    //'!'暗示无出路    

            }  

            return OK; 

}

int Pass(MazeType *maze, PosType curpos )  //判断当前位置可否通过

     if ((curpos.x < 1) || (curpos.x >= maze->lie))

            return ERROR; 

     if ((curpos.y < 1) || (curpos.y >= maze->hang))

            return ERROR;  

     if (maze->a[curpos.y][curpos.x]==' ')

            return OK;      

     else    return ERROR;

}  

int FootPrint(MazeType *maze,PosType curpos) //留下足迹

{     

     maze->a[curpos.y][curpos.x]='*';    

     return OK;

}  

int MarkPrint(MazeType *maze,PosType curpos) //留下不能通过的标记

{    

     maze->a[curpos.y][curpos.x]='@';   

     return OK;

}

PosType NextPos(PosType curpos,int di)

//返回当前位置的下一位置

{

     PosType pos=curpos;

     switch(di)

     {

     case 1: //右东

            pos.x++;

            break;

     case 2:  //下南     

            pos.y++;    

            break;   

     case 3:  //左西       

            pos.x--;    

            break;   

     case 4:  //上北     

            pos.y--;     

            break;    

}    

     return  pos;

}  

//若迷宫有解,则求得一条存放在栈中(从栈底到栈顶),并返回OK,否则返回ERROR

int  MazePath(MazeType *maze,PosType start,PosType end)

{    

     PosType curpos;     

     SqStack *S=(SqStack *)malloc(sizeof(SqStack));   

     InitStack(S);   

     SElemType *e;    

     e=(SElemType *)malloc(sizeof(SElemType));   

     curpos=start;    //设定当前位置为入口位置   

     int curstep = 1;    //探索第一步

     do    {       

            if(Pass(maze,curpos))  //当前位置可通过    

            {              

                   FootPrint(maze,curpos);          

                   e->ord=curstep;    

                   e->seat=curpos;    

                   e->di=1;    

                   Push(S,e);

                   if(curpos.x==end.x&&curpos.y==end.y) 

                          return (OK);     

                   curpos=NextPos(curpos,1);     

                   curstep++;   

            }   

            else    

            {        

                   if(!StackEmpty(S))    

                   {          

                          Pop(S,e);              

                          while(e->di==4&&!StackEmpty(S))   //栈不空但栈顶位置四周均不通     

                          {       

                                 MarkPrint(maze,e->seat); 

                                 Pop(S,e);     

                          }     

                          if(e->di<4)           //栈不空且栈顶位置四周有其他位置未探索    

                          {        

                                 e->di++;       

                                 Push(S,e);                 

                                 curpos=e->seat;                 

                                 curpos=NextPos(curpos,e->di);    

                          }     

                   }     

            }    

     }

     while(!StackEmpty(S));

     return ERROR;

}  

void  PrintMaze(MazeType *maze)         //打印迷宫 

{    

     int i,j,k,n;   

     int c[999],d[999];

     for(i=0,k=0;i<=maze->hang;i++) 

     {  

            for(j=0;j<=maze->lie;j++)

            {   

                   printf("%c ",maze->a[i][j]);   

                   if(maze->a[i][j]=='*')   

                   {    

                          c[k]=i;    

                          d[k]=j;    

                          k++;

                   }

            }         

            printf("\n"); 

     }

     n=k;          

     for(k=0;k<n;k++)

     printf("<%d,%d>",c[k],d[k]);

     printf("\n");       

     printf("\n");

}

int main()

{

     int zmg;   

     char ch;    

     printf("                  数据结构课程设计--迷宫问题求解     \n\n");    

     printf("             |----------------------------------------|\n");    

     printf("             |                                        |\n");    

     printf("             |                                        |\n");   

     printf("             |                                        |\n");   

     printf("             |                                        |\n");   

     printf("             |          XXXX    XXXXXXXXXXXXXX   |\n");    

     printf("             |                 XXXXXXX                |\n");    

     printf("             |----------------------------------------|\n");     

     getchar();    

     do   

     {    

            system("cls");   

            fflush(stdin);      

            MazeType *maze=(MazeType *)malloc(sizeof(MazeType));      //设置迷宫的长宽不含外墙    

            printf("请输入迷宫的列数(不含外墙时):");   

            scanf("%d",&maze->lie);     

            printf("请输入迷宫的行数(不含外墙时):");

            scanf("%d",&maze->hang);   

            generatemaze(maze);   

            printf("随机创建迷宫\n");   

            PrintMaze(maze);   

            getchar();   

            getchar();    

            PosType start,end;    

            start.x=1;start.y=1;    

            end.x=maze->lie-1;end.y=maze->hang-1;   

            zmg=MazePath(maze,start,end);   

            if(zmg)      

            {    

                   printf("此迷宫通路为\n");     

                   PrintMaze(maze);    

            }    

            else 

                   printf("此迷宫无通路\n");    //getchar();    

            printf("再次尝试?(Y/N?");

            scanf("%c",&ch);

     }

     while(ch=='Y'||ch=='y');    

     return 0;

}

更多相关推荐:
数据结构-迷宫-实验报告与代码

一需求分析本程序是利用非递归的方法求出一条走出迷宫的路径并将路径输出首先由用户输入一组二维数组来组成迷宫确认后程序自动运行当迷宫有完整路径可以通过时以0和1所组成的迷宫形式输出标记所走过的路径结束程序当迷宫无路...

数据结构实验报告 迷宫

数据结构实验报告实验三迷宫姓名xxx学号xxx专业信息安全实验日期第十二三周周日实验三迷宫一实验目的1了解回溯法在求解迷宫问题中的应用2进一步掌握栈的使用二实验内容用回溯法求解迷宫问题可以用一个栈保存探索的序列...

数据结构实验报告——栈和队列(迷宫图最短路径)

数据结构实验报告书广东机电职业技术学院20##年5月目录一、实验要求(需求分析)...3a.实验目的...3b.实验内容...3c.程序功能...3二、程序分析...42.1存储结构...42.2关键算法分析.…

数据结构上机实验报告-迷宫求解

数据结构上机实验报告迷宫求解陈冠豪20xx2105010101015二O一O年5月26号实现代码ByLea20xx210501includeltstdiohgtincludeltstdlibhgt数据定义typ...

数据结构之迷宫求解实验报告武汉大学

数据结构实验报告迷宫求解问题实验上机环境DevC二程序设计相关信息1实验题目迷宫求解问题问题描述实验题35改进314节中的求解迷宫问题程序要求输出如图314所示的迷宫的所有路径并求最短路径长度及最短路径2实验项...

数据结构实验报告---迷宫问题--葛晨阳

数据结构课程设计设计题目迷宫问题学院信息技术学院专业网络工程班级B1204学号0913120xx9姓名葛晨阳指导老师戴玉洁课程设计日期20xx年7月20日20xx年8月日1实验题目一问题描述输入一个任意大小的迷...

数据结构试验报告-迷宫问题

实验报告:迷宫问题题目:编写一个求解迷宫通路的程序一、需求分析:1)采用二维数组maze[M][N]来表示迷宫,其中:maze[0][j]和maze[M-1][j](0jN-1)及maze[i][0]和maze…

数据结构实验报告-迷宫漫游

实验四迷宫漫游一实验目的1234熟悉并掌握栈的使用熟悉并掌握函数递归的使用验证栈及其基本操作的实现进一步理解算法与程序的关系够将迷宫漫游算法转化为对应的程序二实验内容1实现小型迷宫的递归算法2实现小型迷宫的非递...

数据结构实验-迷宫问题

实验报告

《算法与数据结构》实验报告(20xx)内蒙古大学

内蒙古大学计算机学院amp软件学院算法与数据结构实验报告算法与数据结构实验报告班级姓名学号实验1线性表的应用6学时问题描述一个线性表A中包含有三类字符数字字符字母字符其他字符试写一个函数实现对线性表A的拆分使得...

迷宫求解数据结构课程设计报告

课程设计报告课题名称迷宫问题姓名学号专业班级指导教师目录第一部分课程设计报告3第一章课程设计目的3第二章课程设计内容和要求421问题描述422设计要求4第三章课程设计总体方案及分析431问题分析432概要设计7...

数据结构实验2栈和队列迷宫问题求解

数据结构实验报告实验名称实验2题目3学生姓名班级班内序号学号日期20xx年11月17日1实验要求1实验目的通过选择下面五个题目之一进行实现掌握如下内容进一步掌握指针模板类异常处理的使用掌握栈的操作的实现方法掌握...

数据结构迷宫实验报告(24篇)