C语言停车场管理系统:基于栈与队列的模拟实现

竹里
竹里
发布时间:2026-10-16| 7人浏览过
原创

本文介绍了如何利用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语言数据结构栈与队列应用实践的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。