《数据结构》上机实验报告(迷宫求解)

时间:2024.4.21

(说明:实验报告必须包含下面的每项内容,根据实验情况认真填写,封面必须打印或复印(A4纸),书写上机实验报告内容的纸张也用A4纸,最后从侧面装订)

一【上机实验目的】

1.       了解栈的应用

2.       编写迷宫程序

二【实验环境】

PC机每人1台

三【上机实验内容】

(此次上机实验老师布置的具体任务)

迷宫求解

主要利用栈实现,要求能动态生成迷宫,显示有几条路径,用图形界面显示最合适的路径。

四【上机调试程序流程图】(注:可打印)

(用传统流程图的形式表示)

五【上机调试中出现的错误信息、错误原因及解决办法】

(记录下你调试程序中出现的错误信息的英文提示,分析出错原因及可能的解决办法)

1.       马虎造成的错误

2.       程序的逻辑有问题

3.       语法用错

调试过程中,将整个程序分为一个个子块,逐个解决

六【上机调试后的源程序及还存在的问题】(注:源程序可打印)

(同时记录下你对你编写此程序的其它具体想法,)

#include<stdlib.h>

#include<time.h>

#include<stack>

#include<queue>

using namespace std;

#define OVERFLOW 0

#define OK 1

#define ERROE 0

#define TRUE 1

#define FALSE 0

#define SIZE 102//迷宫的最大范围

typedef int Status;

typedef struct{

       int x;

       int y;

}PosType;//坐标位置

typedef struct {

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

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

}SElemType;

Status Check(char &choice);//确认输入正确

void Random(int mg[SIZE][SIZE],int size,PosType start,PosType end)

{

       int i,j,k;

       srand(time(NULL));     

       for(j=0;j<size;j++)

              mg[0][j]=mg[size-1][j]=1;  //设置迷宫外围"不可走",保证只有一个出口和入口

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

              mg[i][0]=mg[i][size-1]=1;

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

              for(j=1;j<size-1;j++){

                     k=rand()%4; //随机生成0、1、2、3四个数

                     if(k)

                            mg[i][j]=0;

                     else{

                            mg[i][j]=1;

                     }//else

              }

       mg[start.y][start.x]=0;

       mg[end.y][end.x]=0; //将入口、出口设置为"0"即可通过

}

Status Pass(PosType e,int mg[SIZE][SIZE])

{

              if (mg[e.y][e.x]==0)  //0时可以通过 

              return OK;  // 如果当前位置是可以通过,返回1

       return OVERFLOW; // 其它情况返回0

}

Status FootPrint(PosType e,int mg[SIZE][SIZE])

{

       mg[e.y][e.x]=7;

       return OK;

}

PosType NextPos(PosType e,int dir)

{

       PosType E;

       switch(dir){

              case 1:E.x=e.x+1; //向右

                     E.y=e.y;

                     break;

              case 2:E.x=e.x;  //向下

                     E.y=e.y+1;

                     break;

              case 3:E.x=e.x-1; //向左

                     E.y=e.y;

                     break;

              case 4:E.x=e.x;  //向上

                     E.y=e.y-1;

                     break;

             

       }

       return E;

}

Status Equal(PosType e1,PosType e2)

{

       if((e1.x==e2.x)&&(e1.y==e2.y))

              return TRUE;

       return FALSE;

}

Status MarkPath(PosType e,int mg[SIZE][SIZE],int di)

{

       switch(di)

       {case 1://向右

                     mg[e.y][e.x]=11;

                     break;

              case 2://向下

                     mg[e.y][e.x]=12;

                     break;

              case 3://向左

                     mg[e.y][e.x]=13;

                     break;

              case 4://向上

                     mg[e.y][e.x]=14;

                     break;

       }

       return OK;

}

PosType FrontPos(PosType e,int dir)

{

       PosType E;

       switch(dir){

              case 1:E.x=e.x-1; //向左

                     E.y=e.y;

                     break;

              case 2:E.x=e.x;  //向上

                     E.y=e.y-1;

                     break;

              case 3:E.x=e.x+1; //向右

                     E.y=e.y;

                     break;

              case 4:E.x=e.x;  //向下

                     E.y=e.y+1;

                     break;

       }

       return E;

}

Status PathPrint(stack<SElemType> s,int mg[SIZE][SIZE])

{

       SElemType e,front,tail;

       int di;

      

       e=s.top();

       tail=e;

       s.pop();

       MarkPath(e.seat,mg,1);

       while(!s.empty())

       {

              front=s.top();

              s.pop();

              if(Equal(front.seat,FrontPos(e.seat,e.di)))

              {

                     di=e.di;

                     e=front;

                     MarkPath(e.seat,mg,di);

              }

       }

       return OK;

}

Status PathClean(int mg[SIZE][SIZE],stack<SElemType> s)

{

       SElemType e;

       while(!s.empty())

       {

              e=s.top();

              s.pop();

              mg[e.seat.y][e.seat.x]=0;

       }

       return OK;

}

Status MazePath(PosType start,PosType end,int mg[SIZE][SIZE],stack<SElemType> &s)

{

       queue<SElemType> q;

       SElemType e;

       int di=0;

       e.di=di;

       e.seat=start;// 设定"当前位置"为"入口位置"

       q.push(e);

       s.push(e);

       do

       {    

              e=q.front();//得到队首的值

              q.pop();///重复使用时,用这个初始化

              for(di=1;di<=4;di++)

              {

                     e.seat=NextPos(e.seat,di);

                     e.di=di;

                     if(Pass(e.seat,mg))

                     {

                            q.push(e);

                            s.push(e);

                            FootPrint(e.seat,mg);

                            if(Equal(e.seat,end))

                            {

                                   PathPrint(s,mg);

                                   return TRUE;

                            }

                     }

                     e.seat=FrontPos(e.seat,di);    

              }

       }while(!q.empty());

       printf("\n\n囧 ! 不能到达终点!");

       return FALSE;

}

void PrintMaze(int mg[SIZE][SIZE],int size)

{

       int i,j;

              printf("\n");

              for(i=0;i<size;i++)

              {

                     for(j=0;j<size;j++)

                     {

                            switch(mg[i][j])

                            {

                            case 0:

                            case 7:

                                   printf("  ");

                                   break;

                            case 1:

                                   if((1==i&&0==j)||((size-2)==i&&(size-1)==j))

                                          printf("  ");

                                   else

                                          printf("■");

                                   break;

                            case 11:

                                   printf("→");

                                   break;

                            case 12:

                                   printf("↓");

                                   break;

                            case 13:

                                   printf("←");

                                   break;

                            case 14:

                                   printf("↑");

                                   break;

                            }

                     }

                     printf("\n");

              }

              printf("\n");

}

Status Check(char &choice)

{

       while(!(((choice=getchar())=='y')||(choice=='n')||(choice=='Y')||(choice=='N')))//非正确输入

       {

              if(choice!='\n')

              {

                     printf("请输入确定选择(y/n)\n");

                     getchar();

              }

       }

       getchar();//跳过'\n'

       return OK;

}

int main(){

       stack<SElemType> s;

       int mg[SIZE][SIZE]={1},size;

       PosType start,end;

       char choice;

       system("mode con cols=200 lines=200");

       printf("\n==================迷宫最短路径游戏==================");

       printf("\n说明:■不能走的区域");

       printf("\n    '空格'代表可通过的区域");

       printf("\n默认起点为左上角位置,默认终点为右下角位置\n");

       printf("\n============================================\n");

       printf("请输入迷宫边长(3~%d),系统将为你产生一个随机迷宫:",SIZE-2);

       scanf("%d",&size);

       while((size>SIZE-2)||(size<1))

       {

              printf("输入有误!\n");

              printf("请输入迷宫边长(3~%d),系统将为你产生一个随机迷宫:",SIZE-2);

scanf("%d",&size);

       }

       size+=2;//补上外围

       getchar();//跳过'\n'

       start.x=1;start.y=1; //起点坐标

       end.x=size-2;end.y=size-2; //终点坐标

       Random(mg,size,start,end);

    PrintMaze(mg,size);

       while(!((choice=='Q')||(choice=='q')))

       {

              printf("是否使用该迷宫?(y/n)\n");

              Check(choice);

              if((choice=='Y')||(choice=='y'))

              {

                     PathClean(mg,s);

              }

             

              while((choice=='n')||(choice=='N'))

              {

                     while(!s.empty())

                            s.pop();

                     choice=' ';

                     printf("请输入迷宫边长(3~%d),系统将为你产生一个随机迷宫:",SIZE-2);

                     scanf("%d",&size);

                     while((size>SIZE-2)||(size<1))

                     {

                            printf("输入有误!\n");

                            printf("请输入迷宫边长(3~%d),系统将为你产生一个随机迷宫:",SIZE-2);

                            scanf("%d",&size);

                     }

                     size+=2;//补上外围

                     start.x=1;start.y=1;//起点坐标

                     end.x=size-2;end.y=size-2; //终点坐标

                     getchar();//跳过'\n'

             

              Random(mg,size,start,end);

                     PrintMaze(mg,size);

                     printf("是否使用该迷宫?(y/n)\n");

                     Check(choice);

              }

              printf("是否人工选择起点和终点(y/n)?【默认:起点(1,1),终点(%d,%d)】\n",size-2,size-2);

              Check(choice);

              if((choice=='y')||(choice=='Y'))

              {

                     printf("请输入“起点”坐标(1~%d)用空格分隔:",size-2);

                     scanf("%d %d",&start.x,&start.y);

                     while(((start.x>size-2)||start.x<1)||((start.y>size-2)||(start.y<1))||!Pass(start,mg))

                     {

                            if(!Pass(start,mg))  printf("些位置不能为“起点”!\n");

                            else printf("输入有误!\n");

                            printf("请输入“起点”坐标(1~%d)用空格分隔:",size-2);

                            scanf("%d %d",&start.x,&start.y);

                     }

                     printf("请输入“终点”坐标(1~%d)用空格分隔:",size-2);

                     scanf("%d %d",&end.x,&end.y);

                     while(((end.x>size-2)||end.x<1)||((end.y>size-2)||(end.y<1))||!Pass(end,mg)||Equal(start,end))

                     {

                            if(!Pass(end,mg))   printf("些位置不能为“终点”!\n");

                            else if(Equal(start,end)) printf("该位置已为起点!\n");

                            else printf("输入有误!\n");

                            printf("请输入“终点”坐标(1~%d)用空格分隔:",size-2);

                            scanf("%d %d",&end.x,&end.y);

                     }

                     getchar();//跳过'\n'

              }

              MazePath(start,end,mg,s);

           PrintMaze(mg,size);

              printf("退出游戏请输入\"Q\"否则继续游戏!\n");

              choice=getchar();

getchar();//跳过'\n'

       }

       printf("\n==========程序退出,感谢使用!==========\n");

       return 0;

}

七【上机实验中的其他它问题及心得】

(在上机实验中遇到的你不能解决的其它问题,简单描述一下你此次上机的收获及感想)

迷宫问题关键是探索路径和方法,即在探索过程中记录走过的路径,能走通则继续走;如某一位置的下一位置走不通,则要沿原路退回,这点尤其重要。我们需要一个后进先出结构来保存从入口到当前位置的路径,所以对“栈”的应用必不可少。其次,对迷宫的表示方法也很重要,迷宫中每一点用二维数组坐标表示,当前位置四周的四个方向的点的坐标变化也要清楚。每走一步都要时时检测,对于此问题应掌握其方法和思想,不仅在迷宫问题,在其他很多问题中也能有所应用。对今后其他问题的研究会有很大帮助。

在实际的上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次项目可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。

只有当你真正自己一步步的去编写每一行代码时,你才会有所收获。编写程序时,要做好前期规划。同时非常感谢同学和朋友们对我的热心帮助以及我们的李莉丽老师对我的细心指导。

更多相关推荐:
数据结构上机实验报告

实验一线性表的基本操作实验目的学习掌握线性表的顺序存储结构链式存储结构的设计与操作对顺序表建立插入删除的基本操作对单链表建立插入删除的基本操作算法实验内容1顺序表的实践1建立4个元素的顺序表ssqlist123...

数据结构上机实验答案

数据结构实验指导书答案实验一1请编写函数intfunintaintb函数的功能是判断两个指针a和b所指存储单元的值的符号是否相同若相同函数返回1否则返回0这两个存储单元中的值都不为0在主函数中输入2个整数调用函...

数据结构上机实验报告

空间数据结构基础上机实验报告20xx姓名班级地信121学号07122857环境与测绘学院级实验报告1C面向对象程序设计范例1二维坐标点point的C描述实验目的用面向对象的方法定义一个简单的抽象数据结构本例实验...

数据结构第一次上机实验报告

数据结构第一次上机实验报告线性表实验要求1实现顺序表结构的创建插入删除查找等操作2利用上述顺序表操作实现如下程序建立两个顺序表表示的集合集合中无重复的元素并求这样的两个集合的并交和源程序C实现visualstu...

数据结构上机实验报告

计算机科学与技术学院数据结构教程实验报告20xx20xx学年第2学期学生姓名学生专业学生班级学生学号20xx65实验报告一设计人员相关信息姓名学号班级设计日期20xx年6月5日上机环境VisualC60二程序设...

数据结构上机报告实验一

数据结构上机报告年月日姓名学号同组成员1实验题目及要求实验一编写一个程序实现顺序表的各种基本运算并在此基础上完成以下功能1初始化顺序表2依次采用尾插入法插入abcde元素3输出顺序表L4输出顺序表L的长度5判断...

数据结构实验报告格式1

数据结构实验报告格式实验1线性表的基本操作一实验目的1掌握使用VC上机调试线性表的基本方法2掌握线性表的基本操作插入删除查找等运算在顺序和链式存储结构上的实现二实验内容线性表的基本操作的实现三实验要求1认真阅读...

数据结构上机实验题目-20xx

数据结构上机实验题目第一次上机1书P19ADTList基本操作12个1用顺序存储结构实现2用链式存储结构实现2习P182212223习P18225226或要求将结果置于A表中4习P18229230选做题5习P1...

数据结构上机实验报告

数据结构上机实验报告1实习题目问题描述假设某银行有四个窗口对外接待客户从早晨银行开门起不断有客户进入银行由于每个窗口在某个时刻只能接待一个客户因此在客户人数众多时需在每个窗口前顺次排队对于刚进入银行的客户如果某...

数据结构上机实验指导书_胡国玲

计算机系第一部分算法与数据结构课程实验概述一实验目的算法与数据结构是计算机专业的主干课程和必修课程之一其目的是让大家学习分析和研究数据对象特征掌握数据组织方法和计算机的表示方法以便选择合适的数据逻辑结构和存储结...

北工大数据结构上机实验报告1

实验一报告姓名学号完成日期20xx年4月7日题目设有n个人坐在一个圆桌周围现从第s个人开始报数数到第m的人出列然后从出列的下一个人重新开始报数数到第m的人又出列如此反复直到所有的人全部出列为止Josephus问...

数据结构上机实验20xx_blue

计算机软件技术基础20xx实验报告I数据结构031020xxx张三数据结构上机实验题20xx报告要求简述每一部分的对象目的和要求画出算法程序的流程图说明程序的数据输入要求附源程序清单实学号姓名如DS20xx03...

数据结构上机实验报告(39篇)