栈和循环队列——实现停车场管理系统(含代码讲解)

前言:

        栈和队列是两种常用的数据结构,它们在数据管理方面起着重要的作用。下面我简要介绍一下其概念(可自行跳过):

        (Stack)是一种后进先出(LIFO,Last In First Out)的线性表,它只允许在一端进行插入和删除操作,这一端称为栈顶。另一端是栈底。在栈中,最先插入的元素将最后被删除,即元素出栈的顺序与其插入顺序相反。栈通常用于解决一些需要按照顺序执行的问题,例如深度优先搜索、括号匹配等。

        队列(Queue)是一种先进先出(FIFO,First In First Out)的线性表,它允许在一端插入元素,在另一端删除元素。队列中的元素遵循先入先出(FIFO)的原则,即最早插入的元素将最先被删除。队列常用于解决一些需要按照顺序处理的问题,例如CPU任务调度、打印任务队列等。

        循环队列是一种基于队列的数据结构,它通过循环的方式来实现队列的存储和管理。在循环队列中,元素的添加和移除操作是在队列的两端进行的,添加元素在队尾,移除元素在队头。当队列满时,下一个元素会覆盖队头的元素,从而实现循环。循环队列可以避免队列中的元素浪费空间,并提高队列的使用效率。与栈相比,循环队列具有更加灵活的操作方式,可以在队列的任意位置插入和删除元素,并且可以通过循环的方式来实现队列的无限扩展。此外,循环队列还具有更好的空间利用率,可以避免队列中的元素浪费空间。

题目:

        设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由南向北排列(大门在最北端,最先到达的第一辆车停放在车场的最南端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道即候车场上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。 用栈模拟停车场,用队列模拟车场外的便道,按照从键盘获取的输入数据序列进行模拟管理。每一组输入数据包括3个数据项:汽车“到达”或“离开”信息、汽车牌照号码及到达或离开的时刻,对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离开;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。这里栈以顺序存储结构实现,队列以循环队列实现。 另外,还需设一个临时栈,用于临时停放为要给离开的汽车让路而从停车场。

解题思路:

        我们根据题目的需求来创建主函数调用函数实现其功能首先我们先定义一个整形immo,再使用do { ..... }  while()循环让其是一个死循环无法自行退出在do内语句中构建菜单让用户知道其功能和如何操作,使用switch()...case语句实现选项选择功能,通过cin为immo赋值来执行选项功能,代码如下:

        由于我们只能使用栈和队列来解决这个问题所以解题思路如下:因停车场是一个狭长的通道只允许一辆汽车进出所以我们可以创建一个顺序栈SqStack来表示停车场。代码如下:

再创建一个函数对其初始化:

当停车场停满车后,多余的车只能在停车场外的便道等候,我们称其为候车场,等停车场的车辆离开时,便按先后顺序进入停车场,故设外面的候车场为一个循环队列,我们创建一个循环队列SqQueue表示候车场;代码如下

并对其初始化:

每一组输入数据包括3个数据项:汽车“到达”或“离开”信息、汽车牌照号码及到达或离开的时刻,因此我们创建一个结构体Car包括车牌号CarNo和进场时间CarTime俩个属性!,代码如下图:

我们从题目中所获得的信息就上面这么多了,接下来是我们自己发挥的空间

除了基本库的调用外我们还需要定义全局变量MAXSIZE(停车场内最多的停车数) 值为3,MAXQSIZE(候车场内最多的停车数) 值为4,Prince (每单位停车的费用)值为2。

接着我们需要创建一个函数StackEmpty来判断顺序栈是否为空:

创建一个函数StackFull

创建一个函数StacjLength用来求顺序栈的长度

创建一个Push函数让顺序栈进栈

创建一个Pop函数让顺序栈出栈

首先判断是否为空(也可调用下方判断栈是否为空的函数)然后S.top栈顶自减1,e等于新栈顶的指针。

创建一个DispStack函数用来显示顺序栈中的元素

声明Car类型结构指针*p并初始化赋值为S.top,声明Car类型结构体elem,使用一个for循环条件为j < S的长度,再进行栈是否为空的判断,然后将栈顶自减1并赋值给Car类型的结构体elem再对其输出。

接着循环队列也一样,我们需要判断其是否为空,是否队满求其循环队列的长度

创建EnQueue函数用来让循环队列入队

创建DeQueue函数用来让循环队列出队

创建一个DisQueue函数来显示队中的元素(候车场的车辆信息)

最后是我们的计算费用函数money_all()

对于计算费用如果我们需要精细化的话可以导入我们的万年历不过会麻烦一点,这里我找bug找了俩天才找到连AI都找不到的bug给我找到了,HHH,其实就是我在主函数中忘记初始化另一个暂时停车的停车场S2导致后面计算时数据莫名其妙的丢失!!!所以下次再发布一个有万年历的版本!

接着我们实现菜单的第一的功能车辆的进入,代码如下

第二个功能离开,这个稍微麻烦了一点还需要计算费用,代码如下

第三个功能显示停车场信息

第四个功能显示候车场信息

第五个功能直接break退出

其余无效指令

由于写的有点久,中间还断了,博客可能有点糙!请多见谅,有问题可以在评论区评论!

  • 28
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是使用队列实现停车场管理的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义停车场最大容量 typedef struct { char type; // 到达/离去 int id; // 汽车牌照号码 int time; // 到达/离去的时刻 } Car; typedef struct { int top; // 顶指针 Car data[MAX_SIZE]; // 元素 } ParkStack; typedef struct { int front; // 队头指针 int rear; // 队尾指针 Car data[MAX_SIZE]; // 队列元素 } WaitQueue; int park[MAX_SIZE]; // 停车场 int park_top = -1; // 停车场顶指针 ParkStack park_stack; // 停车场 WaitQueue wait_queue; // 等待队列 // 初始化停车场 void init_park_stack() { park_stack.top = -1; } // 检查停车场是否为空 int is_park_empty() { return park_stack.top == -1; } // 检查停车场是否已满 int is_park_full() { return park_stack.top == MAX_SIZE - 1; } // 将车辆停放在停车场中 int park_car(Car car) { if (is_park_full()) { // 停车场已满,将车辆加入等待队列 if (wait_queue.rear == MAX_SIZE - 1) { // 等待队列已满,无法加入新车辆 return 0; } wait_queue.rear++; wait_queue.data[wait_queue.rear] = car; return 1; } else { // 停车场未满,将车辆停放在停车场内 park_top++; park[park_top] = car.id; park_stack.top++; park_stack.data[park_stack.top] = car; return 1; } } // 从停车场中取出车辆 int unpark_car(Car car) { int i, j, flag = 0; int time = 0; for (i = 0; i <= park_top; i++) { if (park[i] == car.id) { // 找到对应的车辆 flag = 1; time = car.time - park_stack.data[i].time; // 将车辆从停车场中移除 for (j = i; j < park_top; j++) { park[j] = park[j+1]; } park_top--; park_stack.top--; break; } } if (!flag) { // 停车场中没有找到对应的车辆,可能已经离开停车场 return 0; } else { // 计算停留时间和停车费用 int fee = time <= 2 ? 5 : (time - 2) * 3 + 5; printf("车辆 %d 在停车场内停留 %d 分钟,需缴纳停车费用 %d 元\n", car.id, time, fee); if (!is_park_empty()) { // 停车场不为空,将等待队列中的车辆加入停车场 Car next_car = wait_queue.data[wait_queue.front+1]; park_car(next_car); wait_queue.front++; wait_queue.rear--; } return 1; } } // 主函数 int main() { // 初始化停车场和等待队列 init_park_stack(); wait_queue.front = 0; wait_queue.rear = -1; // 输入车辆信息 printf("请输入车辆信息(格式:到达/离去,汽车牌照号码,到达/离去的时刻),输入 E 0 0 结束输入:\n"); char type; int id, time; while (1) { scanf("%c %d %d", &type, &id, &time); getchar(); // 读取输入缓冲区的回车符 if (type == 'E' && id == 0 && time == 0) { break; } Car car = {type, id, time}; if (type == 'A') { // 汽车到达,尝试将车辆停放在停车场中 if (!park_car(car)) { printf("停车场已满,车辆 %d 无法停放\n", car.id); } else { printf("车辆 %d 停放在停车场中\n", car.id); } } else if (type == 'D') { // 汽车离开,尝试将车辆从停车场中移除 if (!unpark_car(car)) { printf("车辆 %d 不在停车场中\n", car.id); } } } return 0; } ``` 注意,上述代码中使用了两个全局变量 `park` 和 `park_top` 来表示停车场,这不是一个很好的实现方式,更好的实现方式是将停车场用一个来表示。在上述代码的基础上,你可以尝试使用实现停车场,以提高代码的可读性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

often_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值