栈与队列的应用:停车场管理

设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出。在停车场内,汽车按到达的先后次序,由北向南依次排列(假设大门在最南端)。若车场内已停满n辆车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一辆车即可开入。当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门后,其他车辆再按原次序返回车场。每辆车离开停车场时,应按其停留时间的长短交费(在便道上停留的时间不收费)。

试编写程序,模拟上述管理过程。要求以顺序栈模拟停车场,以链队列模拟便道。从终端读入汽车到达或离去的数据,每组数据包括三项:①是“到达”还是“离去”;②汽车牌照号码;③“到达”或“离去”的时刻获取系统时间,以秒为单位。与每组输入信息相应的输出信息为:如果是到达的车辆,则输出其在停车场中或便道上的位置;如果是离去的车辆,则输出其在停车场中停留的时间和应交的费用。(提示:需另设一个栈,临时停放为让路而从车场退出的车。)

代码如下:

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

#define PARK_SIZE 5

//定义车的结构体 
typedef struct{
    int plateNum;
    time_t ariTine;//进库时间 
    time_t leaTime;// 出库时间 
}Car; 

//车库,用顺序栈表示 
typedef struct{
    Car park[PARK_SIZE];
    int top;
}seqParkList;

//便道,用链队列表示 
typedef struct LoadNode{
    Car loadnode;
    LoadNode *next;
}LoadNode, *LoadList;

//Park1为车库,Park2为中间车出库来安放为Park1中要暂时出栈的车 
seqParkList Park1, Park2;
//Load为便道 
LoadList Load;

//初始化车库(栈) 
void InitSeqStack(seqParkList *top){
    top->top = -1;
}

//初始化便道(队列) 
void InitQueue(LoadList *Q){
    *Q = (LoadList)malloc(sizeof(LoadNode));
    (*Q)->next = NULL;
}

//车出便道(出队列) 
int DeletQueue(Car *car){
    LoadNode *tcar;
    tcar = Load->next;
    if(tcar == NULL) return 0;
    *car = tcar->loadnode;
    Load->next = tcar->next;
    free(tcar);
    return 1;
}

//车进入小道,并且返回在小道的位置 
int EnterQueue(Car *car){
    //尾插创建队列 
    int order = 0;
    LoadNode *p1, *p2;
    p1 = p2 = Load;
    LoadNode *newCar = (LoadNode *)malloc(sizeof(LoadNode));
    //找到队尾,顺便返回即将被放在便到上车的位置 
    while(p1 != NULL){
        order++;
        p2 = p1;
        p1 = p1->next;
    }
    newCar->loadnode = *car;
    p2->next = newCar;
    newCar->next = NULL;
    return order;
}

//判断车库是否停满 
bool isFull(){
    if(Park1.top == PARK_SIZE - 1) return true;
    return false;
}

//车进车库(进栈) 
int Push(seqParkList *S, Car *car){
    if(S->top == PARK_SIZE - 1) return -1;
    S->top++;
    //进库时获取当前系统的时间 
    time(&car->ariTine);
    S->park[S->top] = *car;
    return S->top;
}

//车出库(出栈) 
int Pop(seqParkList *S, Car *car){
    if(S->top == -1) return S->top;
    *car = S->park[S->top];
    //出车库时获取当前系统的时间 
    time(&car->leaTime);
    S->top--;
    return S->top + 1;
}

//获取车库最外边的车(获取栈顶元素) 
int GetTop(seqParkList *S, Car *car){
    if(S->top == -1) return S->top;
    *car = S->park[S->top];
    return S->top;
}

//返回车库(栈)是否为空 
bool isParkEmpty(seqParkList *park){
    if(park->top == -1) return true;
    return false;
}

//比较两个车的信息 
bool ComCar(Car c1, Car c2){
    if(c1.plateNum == c2.plateNum) return true;
    return false; 
}

//车到达进行相应的操作 
void CarIn(Car *car){
    int order;
    //只要车到来就进入便道,接下来在看要不要进车库 
    order = EnterQueue(car);
    if(isFull()){//如果车库满了则输出该信息 
        printf("车在便道 %d位置\n", order);
    }
    else{//反之车库没满 
        Car tcar; 
        DeletQueue(&tcar);//出便道, 
        order = Push(&Park1, &tcar);//进车库 
        printf("车在车库 %d位置\n", order + 1);
    }
}

//车离开进行相应的操作 
void CarOut(Car *car){
    if(isParkEmpty(&Park1)){
    //如果车库为空便输出相应的信息 
        printf("车库为空!\n");
    }
    else{
        Car c1;
        GetTop(&Park1, &c1); 
        //如果车库最外边不是将要出库的车,便从栈中弹出
        //存入另一个栈,直到车库最外边为要出库的车 
        while(!ComCar(c1, *car)){ 
            Pop(&Park1, &c1);
            Push(&Park2, &c1);
            GetTop(&Park1, &c1);
        }
        int order = Pop(&Park1, &c1);
        //输出出库车在停车场停留时间,并且计算费用,假设10秒2元,11-20s算4元 
        printf("此车在车库停留 %lds 并且花费 %d 元(10s/2元)!\n", c1.leaTime - c1.ariTine, (c1.leaTime - c1.ariTine + 9 ) / 10 * 2);
        //然后把Park2中的车重新放回Park1 
        while(!isParkEmpty(&Park2)){
            Pop(&Park2, &c1);
            Push(&Park1, &c1);
        }
    }
    //车库出了一个车,便道上的车便要进入车库 
    Car c1;
    if(DeletQueue(&c1)){
        Push(&Park1, &c1);
    }
}

int main(){
    InitQueue(&Load);
    InitSeqStack(&Park1);
    InitSeqStack(&Park2);
    seqParkList park1, park2;
    LoadList Load;
    Car car1;
    printf("请输入车牌号,动作\n");
    char action[6];
    scanf("%d %s", &car1.plateNum, action);
    //直到输入车牌号为0结束程序 
    while(car1.plateNum){
        if(strcmp(action, "到达") == 0){
            CarIn(&car1);
        } 
        else if(strcmp(action, "离去") == 0){
            CarOut(&car1);
        }
        printf("请输入车牌号,动作\n");
        scanf("%d %s", &car1.plateNum, action);
    } 
}

运行结果:

猜你喜欢

转载自www.cnblogs.com/HyattXia/p/9886898.html