說明:該程序設(shè)計(jì)采用常見基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)棧和隊(duì)列實(shí)現(xiàn)了一個(gè)簡單停車場管理系統(tǒng)。在具體設(shè)計(jì)中,實(shí)現(xiàn)了系統(tǒng)頁面和停車場的示意圖顯示,通過調(diào)用順序棧和鏈隊(duì)的相關(guān)函數(shù),模擬了實(shí)際停車場的運(yùn)營流程。
目錄
1 任務(wù)內(nèi)容
2 需求分析
2.1 功能需求
2.2 輸入輸出需求
3 概要設(shè)計(jì)
3.1 抽象數(shù)據(jù)類型
3.2 具體功能函數(shù)
4 詳細(xì)代碼
5 使用說明
6 測試結(jié)果與分析
7 總結(jié)感悟
1 任務(wù)內(nèi)容
任務(wù)描述:設(shè)停車場(如下圖所示)內(nèi)只有一個(gè)可停放幾量汽車的狹長通道,且只有一個(gè)大門可供汽車進(jìn)出。汽車在停車場內(nèi)按車輛到達(dá)時(shí)的先后順序,依次由北向南排列(大門在最南端,最先到達(dá)的第一輛車停放在車場的最北端),若車場內(nèi)已經(jīng)停滿幾量汽車,則后來的汽車只能在門外的便道上等候,一旦停車場內(nèi)有車開走,則排在便道上的第一輛汽車即可開入;當(dāng)停車場內(nèi)某車輛要離開時(shí),由于停車場是狹長的通道,在它之后開入車場的車輛必須先退出車場為它讓路,待該車輛開出大門外后,為它讓路的車輛再按原次序進(jìn)入車場。在這里假設(shè)汽車不能從便道上開走。試設(shè)計(jì)一個(gè)停車場管理程序(這里只是一個(gè)假想的停車場管理,并不代表實(shí)際的停車場管理)。
分析提示:汽車在停車場內(nèi)進(jìn)出是按照棧的運(yùn)算方式來實(shí)現(xiàn)的,先到的先進(jìn)停車場;停車場的汽車離開停車場時(shí),汽車場內(nèi)其它汽車為該輛汽車讓路,也是按棧的方式進(jìn)行;汽車在便道上等候是按隊(duì)列的方式進(jìn)行的。因此,將停車場設(shè)計(jì)成一個(gè)棧,汽車讓路也需要另一個(gè)棧來協(xié)助完成,汽車進(jìn)出便道用隊(duì)列來實(shí)現(xiàn)。
基本要求:
1)接受命令和車號(hào),若是汽車要進(jìn)停車場,先判斷停車場棧是否滿,若不滿,則汽車入棧,否則汽車進(jìn)入便道隊(duì)列等候。
2)若是汽車要離開停車場,為給汽車讓路,將停車場棧上若干輛汽車入臨時(shí)棧,等這輛車出停車場后,臨時(shí)棧中的汽車出棧,在回到停車場棧,然后看便道隊(duì)列是否為空,若不空則說明有汽車等候,從隊(duì)頭取出汽車號(hào),讓該車進(jìn)入停車場棧。
3)重復(fù)1),2)直到為退出命令(車號(hào)為0或負(fù)數(shù))。
數(shù)據(jù)結(jié)構(gòu):本設(shè)計(jì)中,棧采用順序棧結(jié)構(gòu),隊(duì)列用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。
核心知識(shí):棧和隊(duì)列。
2 需求分析
2.1 功能需求
一、界面設(shè)計(jì)
1. 停車場管理系統(tǒng)界面
2. 停車場字符模擬示意圖
2. 便道字符模擬示意圖
二、停車場管理
1. 車輛停放:包括車輛停放操作、便道等候操作
2. 車輛離開:包括車輛離開操作、便道車輛停放操作
3. 停車場狀態(tài):顯示當(dāng)前停車場和便道的車輛狀態(tài)
4. 打印停車場車輛信息:顯示當(dāng)前停車場示意圖
5. 打印便道車輛信息:顯示當(dāng)前便道示意圖
2.2 輸入輸出需求
一、系統(tǒng)界面
輸出:“歡迎使用STRANGEX-03停車場管理系統(tǒng)”字樣、停車場管理功能模塊等內(nèi)容。
輸入:單個(gè)字符“A”“B”“C”等內(nèi)容表示要選擇的功能模塊或退出系統(tǒng)的操作。
輸出:執(zhí)行對(duì)應(yīng)功能模塊的相關(guān)操作。
二、車輛停放模塊(在系統(tǒng)界面輸入A)
輸出:當(dāng)前停車場和便道的車輛狀態(tài),提示字樣如“當(dāng)前空余車位為X,便道上共有X輛車在等待,您確定要停車嗎”。
(一)同意停放車輛
輸入:單個(gè)字符“Y”表示同意。
輸出:“請(qǐng)輸入您的車輛編號(hào)”字樣
輸入:5位整型數(shù)字表示車輛編號(hào)
輸出:“您的車輛已停放到停車場”或“您的車輛正在便道等待”
(二)拒絕停放車輛
輸入:單個(gè)字符“N”表示拒絕。
輸出:返回系統(tǒng)界面
三、車輛離開模塊(在系統(tǒng)界面輸入B)
輸出:提示字樣如“請(qǐng)輸入您的車輛編號(hào)”
輸入:5位整型數(shù)字表示車輛編號(hào)
(一)便道上沒有車輛
輸出:執(zhí)行操作后提示“該車輛已離開,X車輛已停入停車場,便道現(xiàn)有X輛車在等待”,
(二)便道上有車輛
輸出:“該車輛已離開停車場”
四、停車場狀態(tài)模塊(在系統(tǒng)界面輸入C)
輸出:當(dāng)前停車場和便道的車輛狀態(tài),字樣如“停車場共有%d個(gè)車位,當(dāng)前空余車位為%d,便道上共有%d輛車在等待”
五、停車場車輛信息模塊(在系統(tǒng)界面輸入D)
輸出:當(dāng)前停車場的模擬示意圖
六、便道車輛信息模塊(在系統(tǒng)界面輸入E)
輸出:當(dāng)前便道的模擬示意圖
3 概要設(shè)計(jì)
3.1 抽象數(shù)據(jù)類型
本程序共設(shè)計(jì)三個(gè)抽象數(shù)據(jù)類型分別表示停車場棧、通道車輛結(jié)點(diǎn)和便道隊(duì)列。
//停車場棧
typedef struct{
int data[StackSize];
??? int top;
} SqStack;
//通道車輛結(jié)點(diǎn)
typedef struct linked_queue{
??? int data;
??? struct linked_queue *next;
} DataNode;
//便道隊(duì)列
typedef struct{
??? DataNode *front;
????DataNode *rear ;
} LinkQuNode;
3.2 具體功能函數(shù)
本程序共有22個(gè)功能函數(shù),具體包括4個(gè)界面設(shè)計(jì)函數(shù)、5個(gè)停車場管理函數(shù)、7個(gè)棧操作函數(shù)、6個(gè)隊(duì)列操作函數(shù)。
//界面設(shè)計(jì)函數(shù)
void MainMenu(); //主菜單界面
void TouchMenu(SqStack *&s,LinkQuNode *&q); //菜單觸控操作
void ParkingLot(SqStack *s); //停車場模擬界面
void WaitingRoad(LinkQuNode *&q); //便道模擬界面
//停車場管理函數(shù)
void ToPark(SqStack *&s,LinkQuNode *&q); //車輛停放操作
void ToLeave(SqStack *&s,LinkQuNode *&q); //車輛離開操作
void GetStatus(SqStack *s,LinkQuNode *q); //顯示當(dāng)前停車場和便道狀態(tài)
void GetParking(SqStack *s); //打印當(dāng)前停車場車輛信息
void GetWaiting(LinkQuNode *&q); //打印當(dāng)前便道車輛信息
//棧操作函數(shù)
void InitStack(SqStack *&s); //初始化棧
void DestroyStack(SqStack *&s); //銷毀棧
bool StackEmpty(SqStack *s); //判斷棧是否為空
bool Push(SqStack *&s,int e); //入棧操作
bool Pop(SqStack *&s,int &e); //出棧操作
bool GetTop(SqStack *s,int &e); //獲取棧頂元素
int CountStack(SqStack *s); //計(jì)算棧內(nèi)元素個(gè)數(shù)
//隊(duì)列操作函數(shù)
void InitQueue(LinkQuNode *&q); //初始化隊(duì)列
void DestroyQueue(LinkQuNode *&q); //銷毀隊(duì)列
bool QueueEmpty(LinkQuNode *q); //判斷隊(duì)列是否為空
bool enQueue(LinkQuNode *&q,int e); //入隊(duì)操作
bool deQueue(LinkQuNode *&q,int &e); //出隊(duì)操作
int CountQueue(LinkQuNode *q); //計(jì)算隊(duì)列內(nèi)元素個(gè)數(shù)
4 詳細(xì)代碼
#include<bits/stdc++.h>
using namespace std;
const int StackSize=10;
//抽象數(shù)據(jù)類型
//停車場棧
typedef struct{
int data[StackSize];
int top;
} SqStack;
//便道車輛結(jié)點(diǎn)
typedef struct linked_queue{
int data;
struct linked_queue *next;
} DataNode;
//通道隊(duì)列
typedef struct{
DataNode *front;
DataNode *rear ;
} LinkQuNode;
//具體功能函數(shù)列表
//界面設(shè)計(jì)函數(shù)
void MainMenu();
void TouchMenu(SqStack *&s,LinkQuNode *&q);
void ParkingLot(SqStack *s);
void WaitingRoad(LinkQuNode *&q);
//停車場管理函數(shù)
void ToPark(SqStack *&s,LinkQuNode *&q);
void ToLeave(SqStack *&s,LinkQuNode *&q);
void GetStatus(SqStack *s,LinkQuNode *q);
void GetParking(SqStack *s);
void GetWaiting(LinkQuNode *&q);
//棧操作函數(shù)
void InitStack(SqStack *&s);
void DestroyStack(SqStack *&s);
bool StackEmpty(SqStack *s);
bool Push(SqStack *&s,int e);
bool Pop(SqStack *&s,int &e);
bool GetTop(SqStack *s,int &e);
int CountStack(SqStack *s);
//隊(duì)列操作函數(shù)
void InitQueue(LinkQuNode *&q);
void DestroyQueue(LinkQuNode *&q);
bool QueueEmpty(LinkQuNode *q);
bool enQueue(LinkQuNode *&q,int e);
bool deQueue(LinkQuNode *&q,int &e);
int CountQueue(LinkQuNode *q);
int main(){
SqStack *park;//定義停車場棧
LinkQuNode *wait;//定義通道隊(duì)列
InitStack(park);
InitQueue(wait);
//調(diào)試專用數(shù)據(jù)
Push(park,12345);
Push(park,67890);
Push(park,63465);
Push(park,89986);
Push(park,53845);
Push(park,65374);
Push(park,15555);
Push(park,25389);
Push(park,24389);
TouchMenu(park,wait);
return 0;
}
//主菜單頁面
void MainMenu(){
printf(" * * * * * * * * * * * * * * * * * * *\n");
printf(" * 歡迎使用STRANGEX-03停車場管理系統(tǒng) *\n");
printf(" * * * * * * * * * * * * * * * * * * *\n");
printf(" * [A]車輛停放模塊 *\n");
printf(" * [B]車輛離開模塊 *\n");
printf(" * [C]顯示當(dāng)前停車場運(yùn)營狀態(tài) *\n");
printf(" * [D]打印停車場內(nèi)的車輛信息 *\n");
printf(" * [E]打印便道上的車輛信息 *\n");
printf(" * [Z]退出系統(tǒng) *\n");
printf(" * * * * * * * * * * * * * * * * * * *\n");
printf("請(qǐng)輸入字母選擇你要使用的功能模塊:");
}
//菜單觸控
void TouchMenu(SqStack *&s,LinkQuNode *&q){
char c;
MainMenu();
while(scanf("%c",&c)){
switch(c){
case 'A':
ToPark(s,q);
MainMenu();
break;
case 'B':
ToLeave(s,q);
MainMenu();
break;
case 'C':
GetStatus(s,q);
MainMenu();
break;
case 'D':
GetParking(s);
MainMenu();
break;
case 'E':
GetWaiting(q);
MainMenu();
break;
case 'Z':
printf("\n歡迎再次使用STRANGEX-03停車場管理系統(tǒng),再見!");
return;
default:
printf("請(qǐng)輸入正確的字母:");
}
c=getchar();//消除回車對(duì)程序的影響
}
}
//停車場模擬界面
void ParkingLot(SqStack *s){
printf(" @ @ @ @ @ @ @ ↑\n");
for(int i=0;i<StackSize;i++){
printf(" @ ");
if(i<CountStack(s)){
printf("車輛%d",s->data[i]);
printf(" @");
}
else{
printf(" @");
}
if(i==0){
printf(" 北");
}
else if(i==StackSize-2){
printf(" ↓");
}
else if(i==StackSize-1){
printf(" 南");
}
else if(i==StackSize/2-1){
printf(" 停車場示意圖");
}
printf("\n");
}
}
//便道模擬界面
void WaitingRoad(LinkQuNode *&q){
printf(" ");
for(int i=0;i<CountQueue(q);i++){
printf("@ @ @ @ @ @ ");
}
printf("@ @\n");
printf(" 出口 ← ");
DataNode *car=q->front;
int k=0;
if(car!=NULL){
while(car->next!=NULL){
printf(" | 車輛%d",car->data);
car=car->next;
}
printf(" | 車輛%d | ",car->data);
}
else {
printf(" ");
}
printf(" ← 入口 便道示意圖\n");
printf(" ");
for(int i=0;i<CountQueue(q);i++){
printf("@ @ @ @ @ @ ");
}
printf("@ @\n");
}
//車輛停放
void ToPark(SqStack *&s,LinkQuNode *&q){
printf("\n※當(dāng)前功能模塊:[A]車輛停放模塊\n");
printf("---------------------------------------------------------------------\n");
printf("當(dāng)前空余車位為%d,便道上共有%d輛車在等待,您確定要停車嗎?\n",StackSize-CountStack(s),CountQueue(q));
int c;
printf("請(qǐng)輸入[Y/N]:");
scanf("%c",&c);
c=getchar();
if(c=='Y'){
int carNo;
printf("請(qǐng)輸入車輛編號(hào):");
scanf("%d",&carNo);
if(Push(s,carNo)){
printf("車輛%d已成功停放在停車場\n",carNo);
}
else{
enQueue(q,carNo);
printf("停車場已滿,車輛%d正在便道上等候\n",carNo);
}
}
else if(c=='N'){
printf("您已確認(rèn)不停車,自動(dòng)返回主菜單\n");
}
else if(c!='N') {
printf("輸入錯(cuò)誤,自動(dòng)返回主菜單\n");
}
printf("---------------------------------------------------------------------\n");
printf("\n");
return;
}
//車輛離開
void ToLeave(SqStack *&s,LinkQuNode *&q){
printf("\n※當(dāng)前功能模塊:[B]車輛離開模塊\n");
printf("---------------------------------------------------------------------\n");
int carNo;
int No=-1;
printf("請(qǐng)輸入您的車輛編號(hào):");
scanf("%d",&carNo);
for(int i=0;i<CountStack(s);i++){
if(carNo==s->data[i]){
No=i;
break;
}
}
if(No==-1){
printf("對(duì)不起,沒有找到您的車輛,自動(dòng)返回主菜單\n");
}
else {
SqStack *temp;
int e;
InitStack(temp);
int x=CountStack(s);
for(int i=x-1;i>No;i--){
Pop(s,e);
Push(temp,e);
}
Pop(s,e);
for(int i=x-1;i>No;i--){
Pop(temp,e);
Push(s,e);
}
if(!QueueEmpty(q)){
deQueue(q,e);
Push(s,e);
printf("車輛%d已離開,車輛%d已成功停放在停車場,便道還有%d輛車在等待\n",carNo,e,CountQueue(q));
}
else {
printf("車輛%d已離開停車場\n",carNo);
}
}
printf("---------------------------------------------------------------------\n");
printf("\n");
return;
}
//停車場狀態(tài)
void GetStatus(SqStack *s,LinkQuNode *q){
printf("\n※當(dāng)前功能模塊:[C]顯示當(dāng)前停車場運(yùn)營狀態(tài)\n");
printf("---------------------------------------------------------------------\n");
printf("停車場共有%d個(gè)車位,當(dāng)前空余車位為%d,便道上共有%d輛車在等待\n",StackSize,StackSize-CountStack(s),CountQueue(q));
printf("---------------------------------------------------------------------\n");
printf("\n");
return;
}
//打印停車場車輛信息
void GetParking(SqStack *s){
printf("\n※當(dāng)前功能模塊:[D]打印停車場內(nèi)的車輛信息\n");
printf("---------------------------------------------------------------------\n");
ParkingLot(s);
printf("---------------------------------------------------------------------\n");
printf("\n");
}
//打印便道車輛信息
void GetWaiting(LinkQuNode *&q){
printf("\n※當(dāng)前功能模塊:[E]打印便道上的車輛信息\n");
printf("---------------------------------------------------------------------\n");
WaitingRoad(q);
printf("---------------------------------------------------------------------\n");
printf("\n");
}
//棧操作函數(shù)
//初始化棧
void InitStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
//銷毀棧
void DestroyStack(SqStack *&s){
free(s);
}
//判斷棧是否為空
bool StackEmpty(SqStack *s){
return (s->top==-1);
}
//進(jìn)棧
bool Push(SqStack *&s,int e){
if(s->top==StackSize-1)
return false;
s->top++;
s->data[s->top]=e;
return true;
}
//出棧
bool Pop(SqStack *&s,int &e){
if(s->top==-1)
return false;
e=s->data[s->top];
s->top--;
return true;
}
//取棧頂元素
bool GetTop(SqStack *s,int &e){
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
//返回棧的元素個(gè)數(shù)
int CountStack(SqStack *s){
return s->top+1;
}
//隊(duì)列操作函數(shù)
//初始化
void InitQueue(LinkQuNode *&q){
q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
q->front=q->rear=NULL;
}
//銷毀隊(duì)列
void DestroyQueue(LinkQuNode *&q){
DataNode *pre=q->front,*p;
if(pre!=NULL){
p=pre->next;
while(p!=NULL){
free(pre);
pre=p;
p=p->next;
}
free(pre);
}
free(q);
}
//判斷隊(duì)列是否為空
bool QueueEmpty(LinkQuNode *q){
return q->rear==NULL;
}
//進(jìn)隊(duì)列
bool enQueue(LinkQuNode *&q,int e){
DataNode *p;
p=(DataNode *)malloc(sizeof(DataNode));
p->data=e;
p->next=NULL;
if(q->rear==NULL)
q->front=q->rear=p;
else{
q->rear->next=p;
q->rear=p;
}
return true;
}
//出隊(duì)列
bool deQueue(LinkQuNode *&q,int &e){
DataNode *t;
if(q->rear==NULL)
return false;
t=q->front;
if(q->front==q->rear)
q->front=q->rear=NULL;
else
q->front=q->front->next;
e=t->data;
free(t);
return true;
}
//返回隊(duì)列的元素個(gè)數(shù)
int CountQueue(LinkQuNode *q){
int sum=1;
DataNode *a=q->front,*b=q->rear;
if(a==NULL&&a==b)
return 0;
while(a!=b){
sum++;
a=a->next;
}
return sum;
}
5 使用說明
系統(tǒng)界面共有五個(gè)功能選項(xiàng)和一個(gè)退出系統(tǒng)選項(xiàng),選擇不同選項(xiàng)根據(jù)提示進(jìn)入下一步操作:
選擇[A]:進(jìn)入車輛停放模塊。
選擇[B]:進(jìn)入車輛離開模塊。
選擇[C]:進(jìn)入顯示當(dāng)前停車場運(yùn)營狀態(tài)模塊。
選擇[D]:進(jìn)入打印停車場內(nèi)的車輛信息模塊。
選擇[E]:進(jìn)入打印便道上的車輛信息模塊。
選擇[Z]:顯示“歡迎再次使用STRANGEX-03停車場管理系統(tǒng),再見!”并退出系統(tǒng),結(jié)束程序。
6 測試結(jié)果與分析
為便于調(diào)試顯示,前期對(duì)停車場棧進(jìn)行以下操作,存入部分?jǐn)?shù)據(jù)。
Push(park,12345);
Push(park,25345);
Push(park,67890);
Push(park,89986);
Push(park,53845);
Push(park,65374);
Push(park,15555);
Push(park,25389);
Push(park,24389);
輸入數(shù)據(jù) | 調(diào)試截圖 |
A Y 54321 |
![]() |
A Y 89745 |
![]() |
A Y 88888 |
![]() |
C | ![]() |
D | ![]() |
E | ![]() |
B 54321 |
![]() |
E | ![]() |
Z | ![]() |
?
7 總結(jié)感悟
在完成棧和隊(duì)列知識(shí)梳理后進(jìn)行本次程序設(shè)計(jì),進(jìn)一步鞏固了對(duì)棧和隊(duì)列的理解。題目本身難度不大,主要就根據(jù)任務(wù)的意思模擬了相關(guān)操作就能實(shí)現(xiàn)。
此次設(shè)計(jì)中主要遇到的一個(gè)比較大的問題是,無法實(shí)現(xiàn)向棧和隊(duì)列中添加string類型數(shù)據(jù),運(yùn)行到相關(guān)Push操作和enQueue操作時(shí)提示“Thread 1 received signal SIGSEGV, segmentation fault.”,也就導(dǎo)致了標(biāo)識(shí)車輛時(shí)只能使用整型數(shù)字表示車輛編號(hào),而無法使用string字符串(即模擬車牌號(hào))進(jìn)行標(biāo)識(shí)。這個(gè)問題目前仍未解決,網(wǎng)上也找不到相關(guān)的資料,可待后續(xù)再研究一下。文章來源:http://www.zghlxwxcb.cn/news/detail-767968.html
本次為了提升對(duì)于棧和隊(duì)列應(yīng)用的理解,沒有使用C++內(nèi)置的STL棧和隊(duì)列。但其實(shí)對(duì)于相關(guān)的函數(shù)可以使用類進(jìn)行封裝,此前在Java中學(xué)習(xí)了面向?qū)ο蟮南嚓P(guān)知識(shí),但在C++中還未實(shí)現(xiàn)過,這也是后續(xù)可以學(xué)習(xí)實(shí)踐的方向。文章來源地址http://www.zghlxwxcb.cn/news/detail-767968.html
到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)】停車場管理系統(tǒng)程序設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!