C语言停车场管理系统:基于栈与队列的模拟实现
本文介绍了如何利用C语言中的栈和队列结构来模拟一个单入口停车场的管理逻辑。系统针对狭长通道内的车辆进出、排队等待以及特殊让位需求进行了算法实现,并附带完整源代码。
一、功能需求分析
停车场系统设计需满足以下核心业务逻辑:
- 物理限制:停车场为单一狭长通道,仅有一个大门,最多容纳
n辆车。 - 入场逻辑:车辆按到达时间顺序由北向南排列(最北端为第一位)。若停车场已满,后续车辆需在门外便道上排队等候。
- 离场与让路:当指定车辆离开时,位于其后的所有车辆必须暂时退出车场为其让路。目标车辆开出后,其他车辆需按原次序重新进入车场。
- 计费规则:仅计算车辆在停车场内停留的时间并收取费用,便道上的等待时间不收费。
- 底层实现:栈采用顺序结构实现以模拟停车场;队列采用链表结构实现以模拟便道。
二、数据结构与函数设计
为了实现上述逻辑,程序定义了两种核心数据结构:
第1步:定义基础数据类型
首先定义表示车辆信息的结构体,包含指令标识符、车牌号码及到达时刻。
typedef struct Node {
char AL; // 指令:A(Arrive), L(Leave), P(Park status), W(Wait status)
int NO; // 车牌号码
int time;// 到达或离去的时刻
} Node;
第2步:构建顺序栈(停车场)
停车场内部逻辑通过顺序栈实现,支持压栈(入站)、出栈(出站)及状态判断。
typedef struct Stack {
struct Node data[MaxSize];
int top;
int num;
} SqStack;
核心操作包括初始化空栈、判断栈满/栈空,以及关键的 POP_SeqStack 函数。在实现该函数时,需创建一个临时辅助栈 p,将目标车辆上方的车辆逐一弹出压入 p,目标车辆出栈并记录耗时,最后再从 p 中将这些车辆依次压回原栈,以确保次序不变。
第3步:构建链表队列(便道)
便道用于暂存无法立即入场的车辆,使用带头节点的链表队列结构。
QNODE { // 队列节点
struct Node data;
QNODE *next;
};
typedef struct linkqueue {
QNODE *front, *rear;
int num;
} LinkQueue;
三、完整代码实现
以下是整合了初始化、入栈、入队、出栈、出队及主循环逻辑的完整源代码。直接复制即可编译运行。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
// 常量定义
#define MaxSize 100
#define QNODE struct QNode
// --- 数据类型定义 ---
typedef struct Node {
char AL;
int NO;
int time;
} Node;
typedef struct Stack {
struct Node data[MaxSize];
int top;
int num;
} SqStack;
QNODE {
struct Node data;
QNODE *next;
}
typedef struct linkqueue {
QNODE *front,*rear;
int num;
} LinkQueue;
// --- 栈操作(停车场) ---
SqStack *Init_SeqStack() {
SqStack *s = (SqStack*)malloc(sizeof(SqStack));
s->top = -1;
s->num = 0;
return s;
}
int ISEmpty_SeqStack(SqStack *s) {
if(s->top == -1) return 1;
return 0;
}
int ISFULL_SeqStack(SqStack *s, int n) {
if(s->top == n-1) return 1;
return 0;
}
void Push_SeqStack(SqStack *p, struct Node s) {
p->top++;
p->data[p->top] = s;
p->num++;
}
// 核心逻辑:出栈及让位过程
int POP_SeqStack(SqStack *s, struct Node car) {
SqStack *p = Init_SeqStack();
int t;
// 1. 将目标车辆上方的车移到临时栈
while(s->data[s->top].NO != car.NO) {
Push_SeqStack(p, s->data[s->top]);
s->top--;
s->num--;
}
// 2. 计算停留时间并移除目标车辆
t = car.time - s->data[s->top].time;
s->top--;
s->num--;
// 3. 将临时栈的车移回原栈
while(!ISEmpty_SeqStack(p)) {
Push_SeqStack(s, p->data[p->top]);
p->top--;
p->num--;
}
return t;
}
// --- 队列操作(便道) ---
LinkQueue *Init_LQueue() {
LinkQueue *q = (LinkQueue *)malloc(sizeof(LinkQueue));
QNODE *p = (QNODE *)malloc(sizeof(QNODE));
p->next = NULL;
q->front = q->rear = p;
q->num = 0;
return q;
}
int ISEmpty_LQueue(LinkQueue *q) {
if(q->front == q->rear) return 1;
return 0;
}
void IN_Lqueue(LinkQueue *q, struct Node s) {
QNODE *p = (QNODE *)malloc(sizeof(QNODE));
p->data = s;
p->next = NULL;
q->rear->next = p;
q->rear = p;
q->num++;
}
struct Node Out_LQueue(LinkQueue *q) {
QNODE *p = q->front->next;
q->front->next = p->next;
q->num--;
if(q->front->next == NULL) {
q->rear = q->front;
}
struct Node result = p->data;
free(p);
return result;
}
// --- 主函数 ---
int main() {
SqStack *parkstack = Init_SeqStack();
LinkQueue *parkqueue = Init_LQueue();
struct Node car;
int n, a = 0, t;
float f;
printf("***************停车场信息查询***************\n");
printf("请输入停车场最大容量n=:");
scanf("%d", &n);
printf("请输入每分钟收取费用f=:");
scanf("%f", &f);
printf("请输入车辆信息\n(Arrive: A, Leave: L, Status: P/W): \n");
scanf("%c,%d,%d", &car.AL, &car.NO, &car.time);
// 处理命令循环
while(car.AL != 'Q') {
if(car.AL == 'A') { // 汽车到达
if(ISFULL_SeqStack(parkstack, n)) {
IN_Lqueue(parkqueue, car); // 进站满,排队
printf("这辆车在门外便道上第%d个位置\n", parkqueue->num);
} else {
Push_SeqStack(parkstack, car); // 进入停车场
printf("这辆车在停车场内第%d个位置\n", parkstack->num);
}
}
else if(car.AL == 'L') { // 汽车离开
t = POP_SeqStack(parkstack, car);
printf("这辆车停留时间为%d,收费为%.2f。\n", t, f*t);
// 如果便道有车,则驶入一辆
if(!ISEmpty_LQueue(parkqueue)) {
Push_SeqStack(parkstack, Out_LQueue(parkqueue));
}
}
else if(car.AL == 'P' && car.NO == 0 && car.time == 0) {
printf("停车场的车数为%d\n", parkstack->num);
}
else if(car.AL == 'W' && car.NO == 0 && car.time == 0) {
printf("候车场的车数为%d\n", parkqueue->num);
}
// 读取下一条指令
fflush(stdin);
scanf("%c,%d,%d", &car.AL, &car.NO, &car.time);
}
printf("输入结束\n");
return 0;
}
四、测试运行
编译并运行程序后,按照提示输入参数与指令。关键字说明如下:
- A (Arrive):车辆到达,要求输入车牌号和当前时间。
- L (Leave):车辆离开,要求输入车牌号和离开时间。
- P (Park count):显示当前停车场内的车辆数量。
- W (Wait count):显示当前便道等待的车辆数量。
- Q (Quit):退出程序。
以下为系统初始化的界面及操作反馈示意:
以上就是《C语言课程设计之停车场管理问题》的详细内容,更多关于C语言数据结构栈与队列应用实践的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













