1. 程式人生 > >棧與佇列的應用:停車場管理

棧與佇列的應用:停車場管理

設停車場是一個可停放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); } }

 

 

執行結果: