数据结构迷宫学校超市选址停车场管理算法.docx
- 文档编号:7261986
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:48
- 大小:353.05KB
数据结构迷宫学校超市选址停车场管理算法.docx
《数据结构迷宫学校超市选址停车场管理算法.docx》由会员分享,可在线阅读,更多相关《数据结构迷宫学校超市选址停车场管理算法.docx(48页珍藏版)》请在冰豆网上搜索。
数据结构迷宫学校超市选址停车场管理算法
课程设计
课程:
数据结构
课程设计名称:
1.迷宫求解路径问题
2.停车场管理问题
3.学校超市选址问题
专业班级:
____________________
学生姓名:
利用栈实现迷宫的求解
一、要解决的问题:
以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
二:
算法基本思想描述:
用一个字符类型的二维数组表示迷宫,数组中每个元素取值“0”(表示通路)或“1”(表示墙壁)。
二维数组的第0行、第m+1行、第0列、第m+1列元素全置成“1”,表示迷宫的边界;第1行第1列元素和第m行第n列元素置成“0”,表示迷宫的入口和出口
走迷宫的过程可以模拟为一个搜索的过程:
每到一处,总让它按东、南、西、北4个方向顺序试探下一个位置;
用二维数组move记录4个方向上行下标增量和列下标增量,则沿第i个方向前进一步,可能到达的新位置坐标可利用move数组确定:
Px=x+move[i][0]
Py=y+move[i][1]
如果某方向可以通过,并且不曾到达,则前进一步,在新位置上继续进行搜索;
如果4个方向都走不通或曾经到达过,则退回一步,在原来的位置上继续试探下一位置。
三:
设计:
1:
数据结构的设计:
(1)定义三元数组元素的结构
typedefstructMazeDirect
{
intDx;//行标
intDy;//列标
intdirect;//走到下一个坐标点的方向
}MazeDirect;
(2)定义链表节点的结构组成
typedefstructLinkNode
{
elemtypedata;//数据域
structLinkNode*next;//指针域
}LinkNode;
(3)定义链栈的头指针
typedefstruct
{
LinkNode*top;//栈的头指针
}LinkStack;
(4)移动数组结构的定义
typedefstruct
{
intx,y;//x为行标,y为列标
}Direction_increm;
2:
算法的设计:
【1】迷宫图的设计
设迷宫为m行n列,利用maze[m][n]来表示一个迷宫,maze[i][j]=0或1;其中:
0表示通路,1表示不通,当从某点向下试探时,中间点有4个方向可以试探,(见图)而四个角点有2个方向,其它边缘点有3个方向,为使问题简单化我们用maze[m+2][n+2]来表示迷宫,而迷宫的四周的值全部为1。
这样做使问题简单了,每个点的试探方向全部为4,不用再判断当前点的试探方向有几个,同时与迷宫周围是墙壁这一实际问题相一致。
假设有6行8列的迷宫,如下图为maze[8][10]构造的迷宫
1111111111
1011101111
1001011111
1000000011
1001101111
1100010001
1011000101
1111111111
【2】试探方向的设计:
在上述表示迷宫的情况下,每个点有4个方向去试探,如当前点的坐标(x,y),与其相邻的4个点的坐标都可根据与该点的相邻方位而得到,如图2所示。
因为出口在(m,n),因此试探顺序规定为:
从当前位置向前试探的方向为从正东沿顺时针方向进行。
为了简化问题,方便的求出新点的坐标,将从正东开始沿顺时针进行的这4个方向(用0,1,2,3表示东、南、西、北)的坐标增量放在一个结构数组move[4]中,在move数组中,每个元素有两个域组成,x:
横坐标增量,y:
纵坐标增量。
Move数组如图3所示。
move数组定义如下:
typedefstruct{
intx;//行
inty;//列
}item;
itemmove[4];
这样对move的设计会很方便地求出从某点(x,y)按某一方向v(0≤v≤3)到达的新点(i,j)的坐标:
i=x+move[v].x,j=y+move[v].y。
x
y
0
0
1
1
1
0
2
0
-1
3
-1
0
图3增量数组move
【3】栈的设计:
当到达了某点而无路可走时需返回前一点,再从前一点开始向下一个方向继续试探。
因此,压入栈中的不仅是顺序到达的各点的坐标,而且还要有从前一点到达本点的方向,即每走一步栈中记下的内容为(行,列,来的方向)。
对于图1所示迷宫,依次入栈为:
top—>
3,4,0
3,3,0
3,2,1
2,2,0
2,1,1
1,1,0
栈中每一组数据是所到达的每点的坐标及从该点沿哪个方向向下走的,对于图3迷宫,走的路线为:
(1,1,0)(2,1,1)(2,2,0)(3,2,1)(3,3,0)(3,4,0)(下脚标表示方向),当无路可走,则应回溯,对应的操作是出栈,沿下一个方向即方向继续试探。
栈中元素是一个由行、列、方向组成的三元组,栈元素的设计如下:
typedefstruct{
intx,y,d;/*横纵坐标及方向*/
}datatype;
栈的定义为:
SeqStacks;
【4】.如何防止重复到达某点,以避免发生死循环:
一种方法是另外设置一个标志数组mark[m][n],它的所有元素都初始化为0,一旦到达了某一点(i,j)之后,使mark[i][j]置1,下次再试探这个位置时就不能再走了。
另一种方法是当到达某点(i,j)后使maze[i][j]置-1,以便区别未到达过的点,同样也能起到防止走重复点的目的,此处采用后一方法,算法结束前可恢复原迷宫。
四:
详细设计;
1.算法的设计思想及流程图
(1)主要函数的功能说明
voidini_stack(LinkStack*)/*初始化链栈*/
intempty_Stack(LinkStack*)/*判断是否为空栈*/
voidpush_Stack(LinkStack*,elemtype)/*入栈*/
elemtypepop_Stack(LinkStack*)/*出栈*/
intsize_stack(LinkStack)/*栈的规模大小*/
(2)算法描述【伪代码描述】
迷宫求解算法思想如下:
(1)栈初始化;
(2)将入口点坐标及到达该点的方向(设为-1)入栈
(3)while(栈不空)
{栈顶元素=>(x,y,d)
出栈;
求出下一个要试探的方向d++;//当遇到死路的时候就出栈,寻找原来点的下一个方向
while(还有剩余试探方向时)
{if(d方向可走)
则{(x,y,d)入栈;
求新点坐标(i,j);
将新点(i,j)切换为当前点(x,y);
if((x,y)==(m,n))结束;
else重置d=0;
}
elsed++;
}
}
五:
源程序清单;
#include
#include
intm,n;
typedefstructMazeDirect
{
intDx;
intDy;
intdirect;
}MazeDirect;/*定义三元数组元素的结构*/
typedefMazeDirectelemtype;
typedefstructLinkNode
{
elemtypedata;
structLinkNode*next;/*定义链表节点的结构组成*/
}LinkNode;
typedefstruct
{
LinkNode*top;/*定义链栈的头指针*/
}LinkStack;
voidini_stack(LinkStack*stack)/*初始化链栈*/
{
stack->top=NULL;
}
intempty_Stack(LinkStack*stack)/*判断是否为空栈*/
{
if(stack->top!
=NULL)
return0;
else
return1;
}
voidpush_Stack(LinkStack*stack,elemtypex)/*入栈*/
{
LinkNode*s;
s=(LinkNode*)malloc(sizeof(LinkNode));
s->data=x;
s->next=stack->top;
stack->top=s;
}
elemtypepop_Stack(LinkStack*stack)/*出栈*/
{
elemtypex;
LinkNode*p;
elemtypetmpNull={0,0,0};
if(stack->top==NULL)
{
returntmpNull;//(NULL)
}
else
{
x=stack->top->data;
p=stack->top;
stack->top=p->next;
free(p);
return(x);
}
}
intsize_stack(LinkStackstack)/*栈的规模大小*/
{
inti;
LinkNode*Numb;
i=0;
Numb=stack.top;
while(Numb!
=NULL)
{
Numb=Numb->next;
i++;
}
returni;
}
intw,t,maze[100][100];
typedefstruct
{
intx,y;//x为行标,y为列标
}Direction_increm;
Direction_incremMazeMove[4]={{0,1},{1,0},
{0,-1},{-1,0}};
typedefMazeDirectTmpType;
intMaze_path()
{
MazeDirecttmp,path;
LinkStacks;
intx,y,Px,Py,d,flag=0;
ini_stack(&s);
tmp.Dx=1;tmp.Dy=1;tmp.direct=-1;
push_Stack(&s,tmp);
while(!
empty_Stack(&s))
{
tmp=pop_Stack(&s);
x=tmp.Dx;y=tmp.Dy;d=tmp.direct+1;//遇到死路的时候,回溯(通过出栈完成)
while(d<4)
{
Px=x+MazeMove[d].x;
Py=y+MazeMove[d].y;
if(maze[Px][Py]==0)
{
tmp.Dx=x;
tmp.Dy=y;
tmp.direct=d;
push_Stack(&s,tmp);
x=Px;y=Py;maze[x][y]=-1;/*标记,防止重复点*/
if(x==m&&y==n)
{
flag=1;
printf("\n到达迷宫出口:
%d,%d",x,y);
printf("\n经过的节点有:
%d个",size_stack(s));
while(!
empty_Stack(&s))
{
path=pop_Stack(&s);
printf("\n(%d,%d,%d)",path.Dx,path.Dy,path.direct);
}
break;
}
elsed=0;
}//结束if
elsed++;
}//结束内部while
}//结束外部while
returnflag;
}
voidmain()
{
printf("请输入迷宫图的行数和列数(输入格式为i,j):
\n");
scanf("%d,%d",&m,&n);
printf("创建迷宫图:
\n");
for(w=0;w { for(t=0;t { scanf("%d",&maze[w][t]); getchar();} } printf("\n找到迷宫的路径(yes/1,no/0): %d",Maze_path()); getch(); } 运行结果: 课程设计题目: 停车场管理系统 一、要解决的问题 停车场是一条可以停放n辆车的狭窄通道,且只有一个大门汽车停放安到达时间的先后依次由北向南排列(大门在最南端,最先到达的第一辆车停在最北端)若停车场已经停满n辆车,后来的汽车在便道上等候,一旦有车开走,排在便道上的第一辆车可以开入;当停车场的某辆车要离开时,停在他后面的车要先后退为他让路,等它开出后其他车在按照原次序开入车场,每两停在车场的车要安时间长短缴费。 要求: 以栈模拟停车场,以队列车场外的便道,按照从终端输入的数据序列进行模拟管理。 每一组数据包括三个数据项: 汽车“到达”或“离去”信息、汽车牌照号码、以及到达或离去的时刻。 对每一组数据进行操作后的信息为: 若是车辆到达,则输出汽车在停车场的内或便道上的位置: 若是车辆离去则输出汽车在停车场内的停留时间和应缴纳的费用(在便道上的停留时间不收费)。 栈以顺序结构实现,队列以链表结构实现。 二、基本要求 (1)界面友好,函数功能要划分好 (2)总体设计应画一流程图 (3)程序要加必要的注释 (4)要提供程序测试方案。 三、算法基本思想描述 由于停车场是一个狭窄通道,而且只有一个大门可供汽车进出,问题要求汽车停车场内按车辆到达时间的先后顺序,依次由北向南排列。 由此很容易联想到数据结构中的堆栈模型,因此可首先设计一个堆栈,以堆栈来模拟停车场,我设计用顺序存储结构来存储停车场内的车辆信息,并给车辆按进栈顺序编号,当停车场内某辆车要离开时,在他之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入停车场。 这是个一退一进的过程,而且让道的汽车必须保持原有的先后顺序,因此可再设计一个堆栈,以之来暂时存放为出站汽车暂时让道的汽车。 当停车场满后,继续进来的汽车需要停放在停车场旁边的便道上等候,若停车场有汽车开走,则按排队的先后顺序依次进站,最先进入便道的汽车将会最先进入停车场,这完全是一个先进先出模型,因此可设计一个队列来模拟便道,队列中的数据元素设计成汽车的车牌号,并以链表的形式存储。 另外,停车场根据汽车在停车场内停放的总时长来收费的,在便道上的时间不计费,因此必须记录车辆进入停车场时的时间和车辆离开停车场时的时间,然后计算、显示费用情况。 四、详细设计 1.数据结构的设计 (1)车辆信息的表示 车辆可看成是一个节点,设计成一个结构体,车辆信息包括: 车牌号码,车辆的进站时间和离开停车的时间,定义如下: typedefstructnode{ charnum[10];//车牌号码 Timereach;//到站时间 Timeleave;//离开时间 }CarNode; (2)时间、栈和队列的定义 时间是由小时和分钟表示的,有两部分数据,所以,类似于复数的表示一样,设计两个变量分别存储小时和分钟。 如: typedefstructtime{ inthour; intmin; }Time; 停车场内用栈表示: typedefstructNODE{ CarNode*stack[MAX+1];//栈用顺序表表示 inttop; }SeqStackCar; 便道上的车辆表示: typedefstructcar{ CarNode*data;//便道上的车用链表表示 structcar*next; }QueueNode; typedefstructNode{ QueueNode*head;//设置头指针、尾指针。 。 QueueNode*rear; }LinkQueueCar; 2.算法的设计思想及流程图 (1)主要函数的功能说明 1、voidInitStack(SeqStackCar*);//车辆节点进栈 当栈未满时,就把到达的车辆进栈。 2、intInitQueue(LinkQueueCar*);//车辆节点进队列 当栈满了时,车辆就进入便道上的队列中 3、intArrival(SeqStackCar*,LinkQueueCar*);//车辆到达登记 车辆到达时,先登记车辆车牌号码。 然后再判断停车场有没有停满,没停满就进栈,停满了就停在便道上,即进队列。 。 4、voidLeave(SeqStackCar*,SeqStackCar*,LinkQueueCar*);//车辆离开处理 通过输入离开车辆的位置处理,然后调用PRINT(CarNode*p,introom);函数进行收费。 。 然后再判断便道上有没有车,如果有,就把便道上的车进停车场内。 5、voidList(SeqStackCar,LinkQueueCar);//显示车场内和便道上的车辆情况 用个switch();函数选择显示车场内或是便道上的车辆情况。 包括对下面两个子函数的调用: voidList1(SeqStackCar*S); voidList2(LinkQueueCar*W);//分别为显示车场和便道上的车辆情况 6、voidPRINT(CarNode*p,introom);//车辆离开是的收费 这个函数由车辆离开的函数调用,以分钟计时算费,但只能计算当天之内的费用,如果第二天的话会导致计费为负或减少。 即只能当天停,当天开走。 。 (2)模块结构及流程图 下图为程序的主流程图,比较清晰的显示了程序的整个运行过程。 如: 图1. (3)主要模块算法描述 本程序最主要的算法就是车辆到达登记的和车辆离开的。 车辆到达: voidArrival(SeqStackCar*Enter,LinkQueueCar*W) 首先定义一个栈和队列的结构体指针为: *p,*t。 然后申请一个车辆信息的内存空间,并把它赋给栈指针。 车辆到达时就输入车牌号,并通过if(Enter->top 来判断该车是进车场内还是进便道上,如果是进车场内就把top加1,显示在车场内的位置,还要输入进车场的时间,然后把该节点进栈。 如果是else就显示该车要停在便道上,并进行进队列的操作。 车辆离开: voidLeave(SeqStackCar*Enter,SeqStackCar*Temp,LinkQueueCar*W) 定义一个整型变量room记录要离开车辆的位置, 定义两个栈指针和一个队列指针, 用个if(Enter->top>0)确保栈不空,然后用个while (1)确保输入的车辆离开位置的合法性。 如果不和法,显示输入有误,要重新输入。 通过while(Enter->top>room)判断离开车辆的位置,如果是中间位置,就要再用一个栈前面临时开出来的车,等要开出的车开出后,再把临时栈的车看进车场内,并要调用PRINT(p,room);这个函数计算显示费用。 然后还要用if((W->head! =W->rear)&&Enter->top 并要进行相应的出队列和进栈操作。 五、源程序清单 #include #include #include #defineMAX3//停车场最大容量为3辆,便于观察 #defineprice0.05 typedefstructtime{//定义时间结构体 inthour; intmin; }Time; typedefstructnode{//定义车辆信息结构体 charnum[10]; Timereach; Timeleave; }CarNode; typedefstructNODE{ CarNode*stack[MAX+1]; inttop; }SeqStackCar; typedefstructcar{ CarNode*data; structcar*next; }QueueNode; typedefstructNode{ QueueNode*head; QueueNode*rear; }LinkQueueCar; voidInitStack(SeqStackCar*); intInitQueue(LinkQueueCar*); intArrival(SeqStackCar*,LinkQueueCar*); voidLeave(SeqStackCar*,SeqStackCar*,LinkQueueCar*); voidList(SeqStackCar,LinkQueueCar); voidprocessloop(); intprnmenu(void); main() { processloop(); } voidprocessloop() { intichoice,ch; SeqStackCarEnter,Temp; LinkQueueCarWait; InitStack(&Enter); InitStack(&Temp); InitQueue(&Wait); ichoice=prnmenu(); while(ichoice<6) { switch(ichoice) { case1: Arrival(&Enter,&Wait);break; case2: Leave(&Enter,&Temp,&Wait);break; case3: List(Enter,Wait);break; } if(ichoice==4)break; ichoice=prnmenu(); } return; } intprnmenu() { intichoice; system("cls"); printf("\n\t-------------------欢迎使用停车场系统---------------\n\n"); printf("\n\t-------------------1.车辆到达登记---------------------\n"); printf("\n\t--------------------2.车辆离开登记---------------------\n");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 迷宫 学校 超市 选址 停车场 管理 算法