【C语言】停车场管理系统丨源码+解析

发布于:2025-06-28 ⋅ 阅读:(11) ⋅ 点赞:(0)

 本文完整实现了基于栈+队列的停车场管理系统,包含详细源码和逐行解析,特别适合复习数据结构与算法综合应用

一、系统设计思路

1. 数据结构设计
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_SIZE 5      // 停车场容量(可修改)
#define PRICE_PER_MIN 0.2 // 每分钟费用

// 车辆信息结构体
typedef struct {
    char license[10];    // 车牌号
    time_t enter_time;   // 进入时间戳
    time_t exit_time;    // 离开时间戳
} CarInfo;

// 栈结构(停车场)
typedef struct {
    CarInfo data[MAX_SIZE];
    int top;             // 栈顶指针
} ParkingStack;

// 队列节点(便道)
typedef struct QueueNode {
    CarInfo car;
    struct QueueNode* next;
} QueueNode;

// 队列结构(便道)
typedef struct {
    QueueNode* front;    // 队首
    QueueNode* rear;     // 队尾
    int count;           // 车辆计数
} WaitingQueue;
2. 核心算法
  • 栈管理停车场​:后进先出(LIFO)模拟车辆停放顺序
  • 队列管理便道​:先进先出(FIFO)保证公平等待
  • 让车处理​:目标车离开时,后方车辆先退栈暂存,再按原序压回
3. 功能模块
  1. 车辆到达处理
  2. 车辆离开计费
  3. 实时显示停车场/便道状态
  4. 时间自动记录与计算

二、完整源码(约250行)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_SIZE 5       // 停车场容量
#define PRICE_PER_MIN 0.2 // 每分钟费用

// 车辆信息
typedef struct {
    char license[10];    // 车牌号
    time_t enter_time;   // 进入时间戳
    time_t exit_time;    // 离开时间戳
} CarInfo;

// 栈结构(停车场)
typedef struct {
    CarInfo data[MAX_SIZE];
    int top;
} ParkingStack;

// 队列节点(便道)
typedef struct QueueNode {
    CarInfo car;
    struct QueueNode* next;
} QueueNode;

// 队列结构(便道)
typedef struct {
    QueueNode* front;
    QueueNode* rear;
    int count;
} WaitingQueue;

// 初始化停车场栈
void initParking(ParkingStack* ps) {
    ps->top = -1;
}

// 初始化等待队列
void initQueue(WaitingQueue* wq) {
    wq->front = wq->rear = NULL;
    wq->count = 0;
}

// 车辆进入便道
void enqueue(WaitingQueue* wq, CarInfo car) {
    QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    newNode->car = car;
    newNode->next = NULL;

    if (wq->rear == NULL) {
        wq->front = wq->rear = newNode;
    } else {
        wq->rear->next = newNode;
        wq->rear = newNode;
    }
    wq->count++;
    printf("车辆 %s 进入便道等待,当前位置:%d\n", car.license, wq->count);
}

// 便道车辆进入停车场
CarInfo dequeue(WaitingQueue* wq) {
    if (wq->front == NULL) {
        CarInfo empty = {"", 0, 0};
        return empty;
    }
    
    QueueNode* temp = wq->front;
    CarInfo car = temp->car;
    wq->front = wq->front->next;
    
    if (wq->front == NULL) {
        wq->rear = NULL;
    }
    
    free(temp);
    wq->count--;
    return car;
}

// 车辆进入停车场
void push(ParkingStack* ps, CarInfo car) {
    if (ps->top == MAX_SIZE - 1) {
        printf("停车场已满!\n");
        return;
    }
    ps->data[++ps->top] = car;
    printf("车辆 %s 进入停车场,车位:%d\n", car.license, ps->top + 1);
}

// 车辆离开停车场
CarInfo pop(ParkingStack* ps) {
    if (ps->top == -1) {
        CarInfo empty = {"", 0, 0};
        return empty;
    }
    return ps->data[ps->top--];
}

// 显示当前状态
void display(ParkingStack* ps, WaitingQueue* wq) {
    printf("\n===== 停车场状态 =====\n");
    if (ps->top == -1) {
        printf("停车场为空\n");
    } else {
        for (int i = 0; i <= ps->top; i++) {
            printf("车位 %d: %s (进入时间: %s", 
                   i + 1, 
                   ps->data[i].license,
                   ctime(&ps->data[i].enter_time));
        }
    }

    printf("\n===== 便道状态 =====\n");
    if (wq->count == 0) {
        printf("便道为空\n");
    } else {
        QueueNode* current = wq->front;
        int pos = 1;
        while (current != NULL) {
            printf("等待 %d: %s\n", pos++, current->car.license);
            current = current->next;
        }
    }
    printf("\n");
}

// 处理车辆离开
void handleExit(ParkingStack* ps, WaitingQueue* wq, char* license) {
    ParkingStack temp; // 临时栈存放让路车辆
    initParking(&temp);
    int found = 0;
    CarInfo exitCar;

    // 在停车场中查找目标车辆
    while (ps->top != -1) {
        CarInfo car = pop(ps);
        if (strcmp(car.license, license) == 0) {
            found = 1;
            exitCar = car;
            break;
        }
        push(&temp, car); // 让路车辆压入临时栈
    }

    // 未找到车辆
    if (!found) {
        printf("未找到车牌为 %s 的车辆\n", license);
        // 还原停车场
        while (temp.top != -1) {
            CarInfo car = pop(&temp);
            push(ps, car);
        }
        return;
    }

    // 计算费用
    exitCar.exit_time = time(NULL);
    double duration = difftime(exitCar.exit_time, exitCar.enter_time) / 60; // 分钟
    double fee = duration * PRICE_PER_MIN;
    printf("车辆 %s 离开,停留时间: %.1f分钟,费用: ¥%.2f\n", 
           license, duration, fee);

    // 将临时栈中的车辆移回停车场
    while (temp.top != -1) {
        CarInfo car = pop(&temp);
        push(ps, car);
    }

    // 检查便道并放行一辆车
    if (wq->count > 0) {
        CarInfo newCar = dequeue(wq);
        newCar.enter_time = time(NULL);
        push(ps, newCar);
    }
}

int main() {
    ParkingStack parking;
    WaitingQueue queue;
    initParking(&parking);
    initQueue(&queue);

    int choice;
    char license[10];

    while (1) {
        printf("\n===== 停车场管理系统 =====\n");
        printf("1. 车辆到达\n");
        printf("2. 车辆离开\n");
        printf("3. 显示状态\n");
        printf("4. 退出系统\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: // 车辆到达
                printf("请输入车牌号: ");
                scanf("%s", license);
                
                CarInfo newCar;
                strcpy(newCar.license, license);
                newCar.enter_time = time(NULL);
                
                if (parking.top < MAX_SIZE - 1) {
                    push(&parking, newCar);
                } else {
                    enqueue(&queue, newCar);
                }
                break;
                
            case 2: // 车辆离开
                printf("请输入离开车牌号: ");
                scanf("%s", license);
                handleExit(&parking, &queue, license);
                break;
                
            case 3: // 显示状态
                display(&parking, &queue);
                break;
                
            case 4: // 退出系统
                printf("系统已退出\n");
                exit(0);
                
            default:
                printf("无效选择,请重新输入\n");
        }
    }
    return 0;
}

三、关键代码解析

1. 数据结构核心
typedef struct {
    CarInfo data[MAX_SIZE]; // 连续内存存储车辆
    int top;                // 栈顶指针(-1表示空)
} ParkingStack;
  • 顺序栈​:数组存储实现高效随机访问,top指向最新车辆
  • 时间复杂度​:入栈/出栈操作仅需O

2. 让路算法实现
while (ps->top != -1) {
    CarInfo car = pop(ps);  // 弹出顶层车辆
    if (匹配目标车牌) {
        found = 1;         // 标记找到目标
        break;
    }
    push(&temp, car);       // 非目标车压入临时栈
}
  • 栈操作模拟​:后入车辆必须先移出(后进先出原则)
  • 暂存机制​:用临时栈保持让路车辆顺序,移回时顺序不变

3. 便道队列管理
typedef struct QueueNode {
    CarInfo car;
    struct QueueNode* next; // 链式存储
} QueueNode;
    4. 时间自动处理
    time_t enter_time = time(NULL); // 获取当前时间戳
    double duration = difftime(exit_time, enter_time) / 60; // 计算分钟数
    • 时间戳记录​:精确到秒的停留时间计算
    • difftime函数​:跨平台安全计算时间差

    四、复习要点总结

    知识点 实现要点 应用场景
    栈(Stack)​ 数组存储+top指针 停车场车辆管理(后进先出)
    队列(Queue)​ 链表实现+头尾指针 便道等待车辆(先进先出)
    时间处理 time_t + difftime() 停车计时与费用计算
    内存管理 malloc/free操作 动态管理队列节点
    算法逻辑 临时栈让路机制 车辆离开时的通道处理

    关键学习方向:

    1. 栈与队列的混合使用​:停车场满时自动切换数据结构
    2. 时间函数实战应用​:理解系统时间戳与差值计算
    3. 链式存储优势​:队列长度动态变化不受数组限制
    4. 数据持久化扩展​:可添加文件保存停车记录(复习fread/fwrite)

    系统运行示例:

    ===== 停车场状态 =====
    车位 1: 京A12345 (进入时间: Wed Jun 27 14:30:25 2025)
    车位 2: 沪B67890 (进入时间: Wed Jun 27 14:35:12 2025)
    
    ===== 便道状态 =====
    等待 1: 粤C54321
    等待 2: 苏D87654

     通过此项目可深入掌握数据结构综合应用系统级C编程的核心技能。

    建议尝试扩展功能:停车记录保存、按小时计费优化、可视化界面等。

    资源推荐:

    C/C++学习交流君羊

    C/C++教程


    网站公告

    今日签到

    点亮在社区的每一天
    去签到