棧與隊列的應用:停車場管理
阿新 • • 發佈:2018-11-01
順序棧 RKE ring 結束程序 order cor empty ack inf
設停車場是一個可停放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);
}
}
運行結果:
棧與隊列的應用:停車場管理