1. 程式人生 > >數據結構15:停車場管理系統

數據結構15:停車場管理系統

清空 所有 str return 輸入 調用 ani 不能 一個隊列

隊列(Queue)字符串

實踐是檢驗真理的唯一標準,學習也是如此。本章對棧和隊列做了詳細的講解,為了讓大家能夠學以致用,特推出一個項目供大家練習(包含了本章所有的重要知識點)。

本項目比較燒腦,要求對棧和隊列有一定深度的了解,雖有完整代碼供大家參考,但是建議先自行完成,然後參照本節給出的完整代碼。

項目簡介

設停車場是一個可以停放 n 輛汽車的南北方向的狹長通道,且只有一個大門可供汽車進出。汽車在停車場內按車輛到達時間的先後順序,依次由北向南排列(大門在最南端,最先到達的第一輛車停放在車場的最北端)。

若車場內已停滿 n 輛車,那麽後來的車只能在門外的便道上等候,一旦有車開走,則排在便道上的第一輛車即可開入;當停車場內某輛車要離開時,在它之後進入的車輛必須先退出車場為它讓路,待該輛車開出大門外,其它車輛再按原次序進入車場,每輛停放在車場的車在它離開停車場時必須按它停留的時間長短交納費用。

項目要求:試為停車場編制按上述要求進行管理的模擬程序。要求程序輸出每輛車到達後的停車位置(停車場或便道上),以及某輛車離開停車場時應繳納的費用和它在停車場內停留的時間。

設計思路

停車場的管理流程如下:
  1. 當車輛要進入停車場時,檢查停車場是否已滿,如果未滿則車輛進入停車場;如果停車場已滿,則車輛進入便道等候。
  2. 當車輛要求出棧時,先讓在它之後進入停車場的車輛退出停車場為它讓路,再讓該車退出停車場,讓路的所有車輛再按其原來進入停車場的次序進入停車場。之後,再檢查在便道上是否有車等候,有車則讓最先等待的那輛車進入停車場。

項目中設計到的數據結構

  1. 由於停車場只有一個大門,當停車場內某輛車要離開時,在它之後進入的車輛必須先退出車場為它讓路,先進停車場的後退出,後進車場的先退出,符合棧的“後進先出,先進後出”的操作特點,因此,可以用一個棧來模擬停車場。
  2. 而當停車場滿後,繼續來到的其它車輛只能停在便道上,根據便道停車的特點,先排隊的車輛先離開便道進入停車場,符合隊列的“先進先出,後進後出”的操作特點,因此,可以用一個隊列來模擬便道。
  3. 排在停車場中間的車輛可以提出離開停車場,並且停車場內在要離開的車輛之後到達的車輛都必須先離開停車場為它讓路,然後這些車輛依原來到達停車場的次序進入停車場,因此在前面已設的一個棧和一個隊列的基礎上,還需要有一個地方保存為了讓路離開停車場的車輛,由於先退出停車場的後進入停車場,所以很顯然保存讓路車輛的場地也應該用一個棧來模擬。

因此,本題求解過程中需用到兩個棧和一個隊列。棧和隊列都既可以用順序結構實現,也可以用鏈式結構實現。

程序清單

以棧模擬停車場,以隊列模擬車場外的便道,按照從終端讀入的輸入數據序列進行模擬管理。

每一組輸入數據包括三個數據項:汽車“到達”或“離去”信息、汽車牌照號碼以及到達或離去的時刻。對每一組輸入數據進行操作後的輸出信息為:若是車輛到達,則輸出汽車在停車場內或便道上的停車位置;若是車輛離去,則輸出汽車在停車場內停留的時間和應交納的費用(在便道上停留的時間不收費,停車場費用按照 1 小時 1.5元)。

實現代碼

#include <stdio.h>
#define MAX 3//模擬停車場最多可停的車輛數
//車的必要信息的結構體 typedef struct
{ int number; int arrive_time; }zanInode;
//進入停車場的處理函數 int push(zanInode *park, int *parktop, zanInode car)
{
//如果停車場已滿,該車需進入便道等待(先返回 -1 ,在主程序中處理) if ((*parktop) >= MAX)
  { printf(
"停車場已停滿!需停到便道上.\n"); return -1; }
   else
   {
     //否則將該車入棧,同時進行輸出 park[(*parktop)] = car; printf("該車在停車場的第 %d 的位置上\n", (*parktop)+1); (*parktop)++; return 1; } } //車從停車場中退出的處理函數 zanInode pop(zanInode *park, int *parktop, int carnumber, zanInode *location, int *locationtop)
{
int i; //由於函數本身的返回值需要返回一輛車,所以需要先初始化一個 zanInode thecar; thecar.number = -1; thecar.arrive_time = -1; //在停車場中找到要出去的車 for (i=-1; i<(*parktop); i++)
   {
if (park[i].number == carnumber)
     {
break; } } //如果遍歷至最後一輛車,還沒有找到,證明停車場中沒有這輛車 if (i == (*parktop))
  { printf(
"停車場中沒有該車\n"); }
  else
  {
     //就將該車移出停車場 //首先將在該車後進入停車場的車全部挪至另一個棧中 while ((*parktop)>i+1)
     { (
*parktop)--; location[*locationtop] = park[*parktop]; (*locationtop)++; } //通過以上的循環,可以上該車後的左右車輛全部移開,但是由於該車也要出棧,所以棧頂指針需要下移一個位置,當車進棧時,就直接覆蓋掉了 (*parktop)--; thecar = park[*parktop]; //該車出棧後,還要將之前出棧的所有車,在全部進棧 while ((*locationtop)>0)
     { (
*locationtop)--; park[*parktop] = location[*locationtop]; (*parktop)++; } }
return thecar; } int main()
{
//停車場的棧 zanInode park[MAX]; int parktop = 0;  //棧頂指針 //輔助停車場進行挪車的棧 zanInode location[MAX]; int locationtop = 0;  //棧頂指針 //模擬便道的隊列 zanInode accessroad[100]; int front, rear;  //隊頭和隊尾指針 front = rear = 0; char order;     //進出停車場的輸入命令 int carNumber;   //車牌號 int arriveTime;   //到停車場的時間 int leaveTime;   //離開停車場的時間 int time;      //車在停車場中逗留的時間 zanInode car; printf("有車輛進入停車場(A);有車輛出停車場(D);程序停止(#):\n"); while (scanf("%c", &order))
   {
if (order == #)
     {
break; } switch (order)
     {
case A: printf("登記車牌號(車牌號不能為 -1)及車輛到達時間(按小時為準):\n"); scanf("%d %d", &carNumber, &arriveTime); car.number = carNumber; car.arrive_time = arriveTime; //當有車想要進入停車場時,首先試圖將該車進入停車場 int result = push(park, &parktop, car); //如果返回值為 -1 ,證明停車場已滿,需要停在便道中 if (result == -1)
          {
            //停在便道上 accessroad[rear] = car; printf("該車在便道的第 %d 的位置上\n", rear+1-front); rear++; } break; case D: printf("出停車場的車的車牌號以及離開的時間:\n"); scanf("%d %d", &carNumber, &leaveTime); //當有車需要出停車場時,調用出棧函數 car=pop(park, &parktop, carNumber, location, &locationtop); //如果返回的車的車牌號為-1 ,表明在停車場中沒有查找到要查找的車 if (car.number != -1)
         {
//停留時間,等於進停車場的時間- time = leaveTime - car.arrive_time; printf("該車停留的時間為:%d 小時,應繳費用為:%f 元\n", time, time*1.5); //一旦有車離開停車場,則在便道中先等待的車就可以進入,進入時需設定車進入的時間 if (front != rear)
            { car
= accessroad[front]; printf("在便道上第1的位置上,車牌號為:%d 的車進停車場的時間為:\n", car.number); scanf("%d", &car.arrive_time); park[parktop] = car; front++; parktop++; }
            else
            { printf("便道上沒有等待車輛,停車場不滿!\n"); } } break; default: break; } printf("\n有車輛進入停車場(A);有車輛出停車場(D);程序停止(#):\n"); scanf("%*[^\n]");
     scanf("%*c");//清空緩沖區 }
return 0; }

運行結果:
有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): A 登記車牌號(車牌號不能為
-1)及車輛到達時間(按小時為準): 633 6 該車在停車場的第 1 的位置上 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): A 登記車牌號(車牌號不能為 -1)及車輛到達時間(按小時為準): 634 7 該車在停車場的第 2 的位置上 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): A 登記車牌號(車牌號不能為 -1)及車輛到達時間(按小時為準): 635 8 該車在停車場的第 3 的位置上 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): A 登記車牌號(車牌號不能為 -1)及車輛到達時間(按小時為準): 636 9 停車場已停滿!需停到便道上. 該車在便道的第 1 的位置上 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): D 出停車場的車的車牌號以及離開的時間: 633 10 該車停留的時間為:4 小時,應繳費用為:6.000000 元 在便道上第1的位置上,車牌號為:636 的車進停車場的時間為: 10 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): D 出停車場的車的車牌號以及離開的時間: 634 10 該車停留的時間為:3 小時,應繳費用為:4.500000 元 便道上沒有等待車輛,停車場不滿! 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): A 登記車牌號(車牌號不能為 -1)及車輛到達時間(按小時為準): 637 11 該車在停車場的第 3 的位置上 有車輛進入停車場(A);有車輛出停車場(D);程序停止(#): #

數據結構15:停車場管理系統