停车场管理系统.docx
《停车场管理系统.docx》由会员分享,可在线阅读,更多相关《停车场管理系统.docx(15页珍藏版)》请在冰豆网上搜索。
停车场管理系统
数据结构课程设计报告
停车场管理系统
姓名:
学号:
院系:
班级:
二〇一三年六月
一、需求分析
1.用栈来表示停车场,用队列来表示停车道。
2.用户需输入车辆的必要信息,如车辆的到达或离开,汽车牌号以及到达或离去的时刻。
停车场的容量及单位时间的停车费由编程序者自行设置,结构需输出车辆停车所需缴纳的费用。
3.本程序要求对车辆的动态能够输出具体的信息内容,包括停车或离开的时间,位置,及所需缴纳的停车费。
4.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,有用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在其后。
5.测试数据为:
N=2,输入数据为:
(’A’,1,5),(‘A’,2.,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0).其中:
’A’表示到达,’D’表示离去,’E’表示输入结束。
6.程序执行的命令为:
1)创建栈和队列;2)对车辆的行为进行相应的处理;3)输出车辆的信息
二、概要设计
1.设定栈的抽象数据类型定义:
ADTStack{
数据对象:
D={ai|ai属于Elem,i=1,2……,n,n>=0}
数据关系:
R1={|ai-1,ai属于D,i=2,……,n}
基本操作:
initStack(&S)
操作结果:
构造一个空栈S.
pop(&S,&e)
初始条件:
栈S已存在。
操作结果:
删除S的栈顶元素,并以e返回其值。
push(&S,&e)
初始条件:
栈S已存在。
操作结果:
在栈S的栈顶插入新的栈顶元素e。
lengthstack(S)
初始条件:
栈S已存在。
操作结果:
返回S中的元素个数,即栈的长度。
}ADTStack;
2.设定队列的抽象数据类型定义:
ADTQueue{
数据对象:
D={ai|ai属于Elem,i=1,2,……,n,n>=0}
数据关系:
R1={|ai-1,ai属于D,i=2,……,n}
基本操作:
initqueue(&Q)
操作结果:
构造一个空队列Q.
enqueue(&Q,e)
初始条件:
队列Q已存在。
操作结果:
插入元素e为Q的新的队尾元素。
dequeue(&Q,&e)
初始条件:
Q为非空队列。
操作结果:
删除Q的对头元素,并用e返回其值。
Lengthqueue(Q)
初始条件:
队列Q已存在。
操作结果:
返回Q的元素个数,即队列的长度。
}ADTQueue
3.本程序主要包括三个模块
主程序模块;
intmain()
{
初始化;
do{
接受命令;
处理命令;
}while(命令!
=退出);
}
处理车辆到达模块;
处理车辆离开模块;
各模块之间的调用关系如下:
处理车辆到达模块
↑
主程序模块
↓
处理车辆离开模块
三、详细设计
1.车信息
typedefstructcar_infor
{intlicen_tag;
inttime;
}SElemType;
2.栈类型
typedefstruct
{SElemType*base1;
SElemType*top1;
SElemType*base2;
SElemType*top2;
}Stack;
栈的基本操作是指如下
voidinitStack(Stack&S)
//初始化通道与临时道
voidpop(&S,&e)
//删除S的栈顶元素,并以e返回其值。
Voidpush(&S,&e)
//在栈S的栈顶插入新的栈顶元素e。
Voidlengthstack(S)
//返回S中的元素个数,即栈的长度。
3.队列类型
voidinitQueue(LinkQueue&Q)
//初始化便道
voidEnQueue(LinkQueue&Q,intlicen_tag,inttime)
//通道满时,车辆进便道
voidenqueue(&Q,e)
//插入元素e为Q的新的队尾元素。
Voiddequeue(&Q,&e)
//删除Q的对头元素,并用e返回其值。
VoidLengthqueue(Q)
//返回Q的元素个数,即队列的长度。
4.函数源码
#include
#include
#defineN2
#defineNULL0
#definePRICE1
typedefstructcar_infor
{intlicen_tag;
inttime;
}SElemType;//定义车信息
typedefstruct
{SElemType*base1;
SElemType*top1;
SElemType*base2;
SElemType*top2;
}Stack;//定义栈
typedefstructQnode
{intlicen_tag;
inttime;
structQnode*next;
}Qnode,*QueuePtr;
typedefstruct
{QueuePtrfront;
QueuePtrrear;
}LinkQueue;//定义队列
voidinitStack(Stack&S)//初始化通道与临时道
{S.base1=(SElemType*)malloc(N*sizeof(SElemType));
S.top1=S.base1;
S.base2=(SElemType*)malloc(N*sizeof(SElemType));
S.top2=S.base2;
}
voidinitQueue(LinkQueue&Q)//初始化便道
{Q.front=Q.rear=(QueuePtr)malloc(sizeof(Qnode));
Q.front->next=NULL;}
voidPush1(Stack&S,intlicen_tag,inttime)//车辆进通道
{S.top1->licen_tag=licen_tag;
S.top1->time=time;
S.top1++;}
voidPush2(Stack&S)//让路的车辆从通道暂时离开,进临时道
{S.top2->licen_tag=S.top1->licen_tag;
S.top2->time=S.top1->time;
S.top2++;
S.top1--;}
voidPop(Stack&S)//车辆从临时道回到通道
{S.top2--;
S.top1->licen_tag=S.top2->licen_tag;
S.top1->time=S.top2->time;
S.top1++;}
voidEnQueue(LinkQueue&Q,intlicen_tag,inttime)//通道满时,车辆进便道
{QueuePtrp;
p=(QueuePtr)malloc(sizeof(Qnode));
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
p->licen_tag=licen_tag;
p->time=time;}
voidDeQueue(LinkQueue&Q,Stack&S)//便道上的车辆进通道
{
QueuePtrp;
p=Q.front->next;
Q.front->next=p->next;
if(Q.front->next==NULL)Q.rear=Q.front;
S.top1->licen_tag=p->licen_tag;
S.top1->time=p->time;
S.top1++;
free(p);}
intjudge1(LinkQueueQ,StackS,intlicen_tag)//判断通道及便道与进来或离去的车是否有相同的牌照
{
SElemType*p;
QueuePtrq=Q.front->next;
p=S.base1;
while(p->licen_tag!
=licen_tag&&p!
=S.top1)p++;
if(p==S.top1)//通道中没有相同的牌照
{inti=1;
while(q)
{
if(q->licen_tag==licen_tag)
{i=0;
q=NULL;//直接跳出循环
}
elseq=q->next;
}
returni;}
elsereturn0;
}
voidmain()
{intj;
charA_D;
intlicen_tag,time;
intlasttime=0;
StackS;
LinkQueueQ;
initStack(S);
initQueue(Q);
printf("第一辆车的信息为:
");
A_D=getchar();
while(A_D!
='E')
{
scanf("%d%d",&licen_tag,&time);
/*chary_n;
do//licen_tag与time也可以这样来确定一下
{
if(A_D=='A')printf("确实是车辆进道吗?
yesOrno:
");
if(A_D=='D')printf("确实是车辆离去吗?
yesOrno:
");
y_n=getchar();
if(y_n=='n')
{
printf("请输入正确的AorD:
");
A_D=getchar();
}
}while(y_n!
='y');*/
if(A_D=='A')
{
j=judge1(Q,S,licen_tag);
while(!
j)//直到牌照正确为止
{
printf("入口的“牌照”重叠错误,请重输\n重新输入的“牌照”为:
");
scanf("%d",&licen_tag);
j=judge1(Q,S,licen_tag);
}
while(time{
printf("入口的“时间”错误,请重输\n重新输入的“时间”为:
");
scanf("%d",&time);
}
if(S.top1==S.base1+N)//通道已满
{
EnQueue(Q,licen_tag,time);
inti=0;
QueuePtrp;
p=Q.front;
while(p!
=Q.rear)
{
p=p->next;
++i;
}
printf("车辆%d在便道上的位置为:
%d\n\n下一辆车的信息为:
",licen_tag,i);}
else{
printf("车辆%d在通道上的位置为:
",licen_tag);
Push1(S,licen_tag,time);
printf("%d\n\n下一辆车的信息为:
",S.top1-S.base1);
}
lasttime=time;//进去的时间为最新时间,用来控制输入时间是否正确
}
if(A_D=='D')//输入的信息为'D'
{
if(S.top1==S.base1)printf("通道中没有车,不能离去\n正确的车辆信息为:
");
else{
j=judge1(Q,S,licen_tag);//j==1表示没有可以离去的车辆
while(j)//直到牌照正确为止
{
printf("离去的“牌照”错误,请重输\n重新输入的“牌照”为:
");
scanf("%d",&licen_tag);
j=judge1(Q,S,licen_tag);}
while(timeprintf("离去的“时间”错误,请重输\n重新输入的“时间”为:
");
scanf("%d",&time);}
S.top1--;
while(S.top1->licen_tag!
=licen_tag&&S.top1!
=S.base1)
{//从通道中去找需离去的车辆
Push2(S);}
if(S.top1->licen_tag!
=licen_tag&&S.top1==S.base1)
{//通道中没有符合离去的车辆
S.top1++;//执行完上一while语句时,栈底元素并未出栈
while(S.top2!
=S.base2)Pop(S);//从临时道中回到通道中
QueuePtrp=Q.front->next;
QueuePtrq=p;
while(p&&p->licen_tag!
=licen_tag)
{q=p;
p=p->next;}
q->next=p->next;
printf("车辆%d在便道上,离去时不付费\n\n下一辆车的信息为:
",licen_tag);
if(p->next==NULL)Q.rear=q;
free(p);}
else//通道中有符合离去的车辆
{
printf("车辆%d的停留时间为:
%dmin\n",licen_tag,time-S.top1->time);
printf("车辆%d应付费%d元\n\n下一辆车的信息为:
",licen_tag,PRICE*(time-S.top1->time));
//不需要改变S.top1;执行完上面倒数第三个while语句时,栈底元素并未出栈
while(S.top2!
=S.base2)Pop(S);//临时道中的车辆回到通道中
if(Q.front!
=Q.rear)//便道中的车辆进通道
{
Q.front->next->time=time;//进通道的时间为上一辆离去的时间
DeQueue(Q,S);
}}
lasttime=time;//离去的时间为最新时间,用来控制输入时间是否正确
}
}//if(A_D=='D')
/*elseprintf("入口的A_D输入有误,请重输\n");为什么不能用*/
A_D=getchar();
}//while
}
函数的调用关系图反映了演示程序的层次结构
停车场仍有空余,入栈成功stack.push()
车辆进入A
停车场已满,入栈失败,入队列line.enquene()
后来车辆进入临时栈temp.push(stack.pop())
主程序
车辆离开D
该车离开stack.pop()
让道车回停车场,临时栈弾栈stack.push(temp.pop())
便道车入栈stack.push(line.dequene())
四、调试分析
1.本次作业是设计停车场的管理系统,就需要判断车牌号,及时间的输入的正确性,
输入的数据有比较严格的要求,必须符合实际。
因此对数据需要多次判断。
2.处理车辆到达模块和处理车辆离开模块其空间复杂度为O(m*n);
3.调试过程中,车离开的那一部分经常出现错误,运行结果和预想的不太一样,后来发现是停车场的计数器那出现了问题,使离开后再进入停车场的位置发生了错误。
如果输入的离开时间比到达的时间小,则会出现付费为负值。
五、用户手册
1.本程序的运行环境为DOS操作系统。
2.进入演示程序后,即显示文本方式的用户界面。
接受其他命令后即执行相应运算和显示相应结果。
六、测试结果
输入‘A’、‘1’、‘5’:
构造第一辆车的信息;
输入‘A’、‘2’、‘10’:
构造下一辆车的信息;
依次输入测试数据,结果如用户手册截图。