课程设计名称: 数据结构与算法课程设计
专 业 班 级 : XXXX
学 生 姓 名 : XXX/XXX /XXX /XXX
学 号 : XXXXXXXXXXX/XXXXXXXXXXXX
XXXXXXXXXXX/XXXXXXXXXXXX
指 导 教 师 : XX/XXX
课程设计时间: XXXX年X月XX日 至 XXXX年X月XX日
XXX 专业《数据结构与算法课程设计》任务书
学生姓名 | XXX、XXX XXX、XX | 专业班级 | XXX | 学号 | XXXXXXXXXXXX、XXXXXXXXXXXX XXXXXXXXXXXX、XXXXXXXXXXXX | ||
题 目 | 停车场管理问题 | ||||||
课题性质 | A.工程设计 | 课题来源 | 自拟课题 | ||||
指导教师 | XX XXX | ||||||
主要内容 | 设停车场是一个可停放 n 辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满 n 辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该车辆开出大门外,其他车辆再按照原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。 | ||||||
任务要求 |
| ||||||
参考文献 |
| ||||||
审查意见 | 指导教师签字: 教研室主任签字: XXXX年X月X日 | ||||||
目录
一、实验构想与规划........................................2
(一)实验内容:.................................... 3
(二)实验步骤:.................................... 4
(三)实验环境:.................................... 4
(四)实验评估:.................................... 4
(五)实验细节处理:..............................4
二、软件代码与说明..................................... ..4
(一)停车场功能函数:.............................5
(二)队列操作函数:.................................5
(三)栈操作函数:................................... .6
(四)主函数:........................................... 6
三、实验结果图表及讨论................................ 12
四、结论及心得...............................................16
五、组员工作分配与贡献百分比......................17
六、参考文献......................................... .........17
一、实验构想与规划
对于本实验,我们采用栈和队列来模拟停车场和便道,当车进入停车场时需要进入最里面的车位,当停车场的车位满时,则考虑将后进入的车辆进入到临时便道(队列)。当车离开停车场时,则需要将该车前已被占满的车位中的车辆转移到暂存空间(栈)中,然后将该车移走之后,再将暂存空间中的车辆转移到停车场中。当车辆离开时计算进入时间与离开时间之间的差,按照一分钟0.1元来计算最后所收的金额。对于未进入停车场的便道上的车,未进入就要离去,则不收取停车费用,流程图如下图1-1,图1-2:
图1-1 车辆进入流程图
图1-2 车辆离开流程图
1.设计停车场管理系统的数据结构:包括车辆信息的存储、停车位息的存储等,停车场和暂存空间的栈,便道的队列。
2.实现停车场管理系统的各个功能模块:包括车辆的进出管理、停车位的分配管理等。
3.设计测试用例:模拟不同场景下的车辆进出情况,测试系统的性能,稳定性和各类测试数据能否正常通过等。
4.进行实验并收集数据:记录系统运行的各项指标,如运行时间、内存消耗、时间复杂度、空间复杂度等。
1.设计停车场管理系统的数据结构和功能模块。
2.编写代码实现系统功能。
3.编写测试用例并进行测试。
4.记录和分析实验结果。
5.优化系统设计和代码实现。
1.编程环境:选择合适的C语言编程环境,Visual Studio等。
2.操作系统:实验可在Windows系统下进行。
3.资源准备:保证系统运行所需的资源充分。
1.定性评估:评估系统功能的完整性和稳定性。
2.定量评估:通过测试数据分析系统性能指标,如运行时间、内存消耗等。
3.对比实验结果并总结结论。
1.要保证停车场的长度有限且可变的,就需要宏定义一个maxsize来表示停车场的空间大小,在头部修改大小更加方便。
2.要保证只有一个大门可进出,根据情况满足FILO的特性,则需要用到栈 的数据结构。
3.可以运用链式队列来定义便道使得增删更加方便,增加了代码的方便性。
4.若要将便道里面的车驶入停车场中,则需要先按照队列的先进先出的特点,将便道里面的车辆驶入停车场里面。
5.要计算车辆停留时间的金额总和,则需要将离开时间与驶入时间做差,按照每分钟0.1元的价格收费。
本程序共设计三个抽象数据类型分别表示停车场栈、通道车辆结点和便道队列。
//用顺序栈来定义停车场 typedef struct{ Car data[maxsize]; int Top; }SeqStack; //用链队列定义便道 typedef struct node{ Car data; struct node *next; }QueueNode; //通道队列 typedef struct{ QueueNode *front; QueueNode *rear; }LinkQueue; |
//汽车抵达 void Car_In(SeqStack*S,LinkQueue*q); //汽车离开 void Car_Out(SeqStack*S,LinkQueue*q); //打印停车场车辆信息 void GetPark(SeqStack *s); //显示当前停车场运营状态 void GetStatus(SeqStack* s, LinkQueue* q); //打印便道车辆信息 void GetWait(LinkQueue *q); //打印车的栈的位置 void ParkingLot(SeqStack *s); //检查停车场内有无该车辆 int SearchParking(SeqStack* p, Car c); //便道模拟界面 void WaitingRoad(LinkQueue *q); |
//返回队列的元素个数 int CountQueue(LinkQueue *q); //出队列 离开便道(出队) Car deQueue(LinkQueue *q); //队列操作函数 //初始化 LinkQueue* InitQueue(); //判断队列是否为空 bool QueueEmpty(LinkQueue *q); |
//返回栈的元素个数 int CountStack(SeqStack *s); //初始栈(停车场) SeqStack* InitStack(); //离开停车场(出栈) Car PopStack(SeqStack*S); //进入停车场(入栈) void PushStack(SeqStack*S,Car x); |
//主函数 int main(){ SeqStack *S = InitStack(); LinkQueue *q = InitQueue(); //开始界面 system("title 停车场管理系统"); system("mode con cols=60 lines=35");//设置窗口大小 //字体颜色 color(11); int index = 1; while(index){ MainMenu(); char c = _getch(); switch(c){ case 'A': Car_In(S,q); //程序暂停和清空控制台 system("pause"); system("cls"); break; case 'B': Car_Out(S,q); //程序暂停和清空控制台 system("pause"); system("cls"); break; case 'C': GetStatus(S,q); //程序暂停和清空控制台 system("pause"); system("cls"); break; case 'D': GetPark(S); //程序暂停和清空控制台 system("pause"); system("cls"); break; case 'E': GetWait(q); //程序暂停和清空控制台 system("pause"); system("cls"); break; case 'Z': printf("\n欢迎再次使用STRANGEX-03停车场管理系统,再见!"); index = 0; return 0; default: printf("请输入正确的字母:"); //程序暂停和清空控制台 system("pause"); system("cls"); } } } |
汽车抵达:若停车场未满则输入车牌号、抵达时间直接进入,若停车场已满输入信息后将车停入便道;这一过程将停车场以栈的形式展现。
//汽车抵达 void Car_In(SeqStack*S,LinkQueue*q){ Car x; printf("请输入您的车牌号以及抵达时间(eg:U8588 2 15):"); scanf("%s %d %d",x.id,&x.t1.h,&x.t1.m); if(S->Top == maxsize-1){ x.loc2 = ++i;//便道被占用位置加一 enQueue(q,x); printf("停车场已满,麻烦您进入便道位置 %d 等待\n",x.loc2); }//停车场已满进入便道 else{ x.loc1 = S->Top + 2;//停车场被占用位置加一 PushStack(S,x); printf("成功进入停车场,您的位置为 %d \n",x.loc1); } } |
汽车离开:以队列模拟车场外的便道,若停车场没有车辆直接返回程序;若停车场有车且要退出的车辆在最外面,则直接退出且算出所需费用;若退出车辆后面有车且便道无车,则需要后面的车为将要退出的车辆让路且算出所需费用;若退出车辆后面有车且便道有车,则后面的车为将要退出的车辆让路且车辆退出后且算出所需费用,让路车辆与便道车辆依次进入停车场。
//汽车离开 void Car_Out(SeqStack*S,LinkQueue*q){ Car x,t,fir; int flag = 0; if(S->Top == -1){ printf("停车场内未有停车车辆\n"); return ; } if(S->Top == maxsize-1 && QueueEmpty(q) ) { printf("停车场车辆已停满\n"); printf("便道上没有车辆\n"); //fir = deQueue(q); // 便道有车 //flag = 1; } else if(S->Top == maxsize-1 && !QueueEmpty(q)) { printf("停车场车辆已停满\n"); printf("便道上有车辆\n"); fir = deQueue(q); // 便道有车 flag = 1; } SeqStack*Temp = InitStack();//临时栈 printf("请输入汽车车牌号以及离开时间(eg:U8588 3 15):"); scanf("%s %d %d",x.id,&x.t2.h,&x.t2.m); if(!SearchParking(S,x)){ printf("车牌号错误,未发现该停车车辆\n"); return; } while(strcmp(x.id,S->data[S->Top].id)!=0){ t = PopStack(S); printf("车牌号为%s的车让路\n",t.id); PushStack(Temp,t); }//有车辆离开,其他车辆需要按顺序让路
t = PopStack(S); t.t2.h = x.t2.h; t.t2.m = x.t2.m; float per; per = (t.t2.h-t.t1.h)*60 + (t.t2.m-t.t1.m);//停车总时长 int t1,t2; if (t.t2.m >= t.t1.m) { t2 = t.t2.m - t.t1.m; t1 = t.t2.h - t.t1.h; } else { t2 = t.t2.m + 60 - t.t1.m; t1 = t.t2.h - t.t1.h - 1; }//考虑借位
printf("车牌号为%s的车辆开出\n",t.id);
while(Temp->Top!=-1){ t = PopStack(Temp); t.loc1 = S->Top + 1 ; printf("车牌号为%s的车辆返回停车位\n",t.id); PushStack(S,t); }//车辆开出后,让位车辆按照原有顺序回到停车位置
//考虑便道等候车辆 if(flag){ PushStack(S,fir); fir.loc1 = S->Top+1; // fir.loc1 = S->Top+1; printf("车牌号为%s的车辆进入停车场\n",fir.id);
flag--; i--; // 便道车位变化 }
printf("本次停留时间为 %d 小时 %d 分钟,共计 %.2lf 元\n",t1,t2,per*price); } |
显示当前停车场运营状态
//显示当前停车场运营状态 void GetStatus(SeqStack* s, LinkQueue* q) { printf("\n※当前功能模块:[C]显示当前停车场运营状态\n"); printf("-------------------------------------------------------\n"); printf("停车场共有%d个车位,当前空余车位为%d,便道上共有%d辆车在等待\n", maxsize, maxsize - CountStack(s), CountQueue(q)); printf("-------------------------------------------------------\n"); printf("\n"); return; } |
打印停车场车辆信息:通过ParkingLot函数将停车场的车辆信息以及它们的具体排布情况显示出来。
//打印停车场车辆信息 void GetPark(SeqStack *s) { printf("\n※当前功能模块:[D]打印停车场内的车辆信息\n"); printf("-------------------------------------------------------\n"); ParkingLot(s); printf("-------------------------------------------------------\n"); printf("\n"); } |
打印便道车辆信息:通过waitingRoad函数将便道上车辆的信息与具体的排布情况显示出来。
//打印便道车辆信息 void GetWait(LinkQueue *q){ printf("\n※当前功能模块:[E]打印便道上的车辆信息\n"); printf("-------------------------------------------------------\n"); WaitingRoad(q); printf("-------------------------------------------------------\n"); printf("\n"); } |
打印车的栈的位置,输出停车场中车的位置,将栈结构更直观的体现出来。
//打印车的栈的位置 void ParkingLot(SeqStack *s){ printf(" @ @ @ @ @ @ @ ↑\n"); for(int i=0;i<maxsize;i++){ printf(" @ "); if(i<CountStack(s)){ printf("车辆%s",s->data[i].id); printf(" @"); } else{ printf(" @");
} if(i==0){ printf(" 北"); } else if(i==maxsize-2){ printf(" ↓"); } else if(i==maxsize-1){ printf(" 南"); } else if(i==maxsize/2-1){ printf(" 停车场示意图"); } printf("\n"); } } |
便道模拟界面,输出便道中车的位置,将队列结构更直观的体现出来。
//便道模拟界面 void WaitingRoad(LinkQueue *q){
printf(" "); for(int i=0;i<CountQueue(q);i++){ printf("@ @ @ @ @ @ "); } printf("@ @\n"); printf(" 出口 ← "); QueueNode *car=q->front; int k=0; if(car!=NULL){ while(car->next!=NULL){ printf(" | 车辆%s",car->data.id); car=car->next; } printf(" | 车辆%s | ",car->data.id); } else { printf(" "); } printf(" ← 入口 便道示意图\n"); printf(" "); for(int i=0;i<CountQueue(q);i++){ printf("@ @ @ @ @ @ "); } printf("@ @\n"); } |
顺利进入主界面,在主界面有六个对应按钮,如图3-1。
图3-1 主界面
实现停车进入功能(第一个按钮),输入车辆的牌号、到达时间,若停车场还存在空位,将车辆停入停车场同时反馈出车辆所停位置,如图3-2; 若停车场已停满,车辆将进入便道等待并且反馈出在便道所处位置,如图3-3。
图3-2 车辆进入停车场
图3-3 车辆进入便道
实现车辆离开功能(第二个按钮),输入车辆的牌号、离开时间,若车辆处于停车场的最南侧则直接退出停车场并且打印出停车时长与所需金额,如图3-4;若车辆后面存在车辆且便道上无车,则需其他车辆为其让路退出,让路车辆依次再次进入停车场,打印出停留时间与所需金额,如图3-5;若车辆后面存在车辆且便道上有车,则需其他车辆为其让路退出,让路车辆与便道的第一辆车辆依次再次进入停车场,打印出停留时间与所需金额,如图3-6。
图3-4 停车时长与金额
图3-5 车辆让路退出
图3-6 车辆让路退出且便道车进入停车场
查阅停车场运营信息(第三个按钮),显示出停车场总共车位与剩余车位以及便道车辆的等待情况,如图3-7。
图3-7 显示停车场的运营状态
查阅停车场的停车情况(第四个按钮),显示出车辆停占的具体情况,如图3-8。
图3-8 打印停车场内的车辆信息
查阅便道的车辆情况(第五个按钮),显示出车辆便道具体等待状况,如图3-9。
图3-9 打印便道上的车辆信息
数据结构是一门重要的专业基础课,通过这次课程设计使我了解了语言程序设计的思想,并且掌握了程序设计的基本方法为后续课程打下了坚实的基础。同时,这次课程设计又是一次实践性较强的知识应用。在对我进行程序设计基础理论与技术技巧能力训练的同时,更加培养了我解决实际问题的编程能力。
在设计过程中,首先要解决的是与同学的合作,搂下来分工与协商,共同探讨,大家取长补短,认清自己的不足之处和薄弱环节,加以弥补和加强,要做出一个好的程序就要有不懈追求的精神和对理想崇高的追求,有一种不完成不罢休的精神。c语言作为一种高级编程语言具有力便灵活的特点,适合各种类型的软件开发,为我们以后学习单片机非常有用。
在设计初期,根据题目的要求和所学的知识车库中的车辆是先进后出的,是栈结构,便道上的车辆是先进先出的,是一个队列,结构很明显,应用栈和队列来解决这个问题,这样也可以起到一个连续记录数据的功能,完成设计要求的任务。
在实际的编写停车场管理系统时,我需要设计高效的算法来实现车辆的进出、停车位的分配等功能。通过学习算法知识,我可以不断优化系统的性能,提高系统的效率和稳定性;同时错误处理和异常情况处理很重要:在实际运行的停车场管理系统中,可能会遇到各种异常情况和错误。通过学习错误处理和异常处理机制,我可以更好地处理这些情况,保证系统的安全和稳定运行。
总之,这次课程设计挖掘了我们潜在的能力,也使我们对编程更加有兴趣,为以后的学习打下了良好的基础。
组员姓名 | 工作内容 | 贡献比 |
XXX |
| 40% |
XX |
| 20% |
XXX | 1. 撰写实验报告(心得体会) 2. 撰写实验报告(实验结果图表及讨论) 3. 参考文献的收集([5]~[6]) 4. PPT撰写(实验结果及分析的内容编写) 5. PPT的最后的修改完善 | 20% |
XXX | 1. 报告撰写(主要内容) 2. 报告撰写(任务要求) 3. 参考文献收集([1]~[4]) 4. 报告撰写(代码整合:栈操作、队列操作函数) 5. 报告整合 6. 制作PPT(1-7页) | 20% |
六、参考文献
1.李春葆.数据结构与算法教程[M].清华大学出版社,2005. 2.严蔚敏.数据结构(C语言版).清华大学出版社,2021. 4.托马斯·科尔曼、查尔斯·雷瑟尔森、罗纳德·李维斯特、克利福德·斯坦.算法导论.麻省理工学院出版社,2009. 5.甘勇,李晔,卢冰.C语言程序设计[M].北京:中国铁道出版社,2014. 6.耿国华.数据结构--C语言版描述.高等教育出版社,2006. |