實驗二 線性表的應用(二)
【實驗類別】設計型實驗
【實驗目的】
1.熟悉線性表的順序儲存和鏈式儲存各自的特點及運算;
2.熟練掌握線性表的基本操作在不同儲存結構中實現演算法;
3.通過本次實驗幫助學生加深對C語言的使用(特別是函式的引數呼叫、指標型別的應用和連結串列的建立等各種基本操作)
4.對一個實際的問題能夠進行合理的需求分析,選擇合適的儲存結構,設計完成符合實際需要的功能。
【實驗學時】4學時
【實驗組人數】1人。
【實驗裝置環境】計算機,VC++6.0,C-Free等
【實驗內容】
1、停車場的管理(4學時)
【問題描述】設有一個可以停放n輛汽車的停車場,它有二個大門可以供車輛進出,其中一個進,一個出。車輛到達停車場後任意選擇空閒停車位停放,每個停車位按順序編號。如果停車場已放滿n輛車,則後來的車輛只能停在停車場大門外的便道上等待,一旦停車場裡有車開走,則排在便道上的第一輛車就進入停車場。每輛車離開停車場時,都應根據其在停車場的逗留時間交費。如果停留在便道上的車未進停車場就要離去,允許其離去,不收停車費,並且仍然保持在便道上等待的車輛順序。編制一程式模擬停車場的管理。
[基本要求] 1、要求程式輸出每輛車到達後的停車位置(停車場或便道上);
2、某輛車離開停車場時應交納的費用和停留時間;
3、可以隨時檢視停車場及便道的狀態。
4、可以隨時檢視空閒停車位。4、可以隨時檢視空閒停車位。
【實現提示】
1.本題可以用靜態連結串列作為儲存結構
2.汽車模擬輸入格式為:(到達\ 離去, 汽車牌照號碼,到達\離去的時刻), 例如: (‘A’,1,5) 表示1號車在5時刻到達;(‘D’, 5,20) 表示5號車在20時刻離開;結束標誌為: (‘E’,0,0)。
說明:以上題目除了要求的基本功能以外,可以根據實際調研的需求自由發揮,增加可行功能,使系統的功能應用更加完善。
#include "stdio.h"
#include "malloc.h"
#define MAX 3 //停車站所能容納的最大車數量
#define SIZE_INIT_LANE 100
#define INCREASE 10 //沒次增量
#define PRICE 10; //單價
typedef int Elemtype;//汽車號變數型別
typedef struct
{
Elemtype Car_license; //汽車號碼
int Car_Inbound; //入站時刻
int Car_Outbound; //出站時刻
int flag; //是否有車標誌
struct Stop_car* next;
}Stop_car;//停車場用靜態連結串列
typedef struct
{
Elemtype* Car_license;
int num;
int size;
}Lane;//便車道動態陣列
//全域性變數
int Stop_car_Num;//停車站車數量
//函式宣告
int Init_Stop_car(Stop_car* s);
int Init_Lane(Lane* L);
int push_car(Elemtype carNum, int time, Stop_car* s, Lane* L);
int pull_car(Elemtype carNum, int time, Stop_car* s, Lane* L);
Stop_car* find_INSTOP(Stop_car* s, Elemtype carNum);
int find_Lane(Lane* L, Elemtype carNum);
void meau(Stop_car* s, Lane* L);
int main()
{
Stop_car* s;
s = (Stop_car*)malloc(sizeof(Stop_car));
Lane* L;
L = (Lane*)malloc(sizeof(Lane));
Init_Stop_car(s);
Init_Lane(L);
meau(s, L);
return 0;
}
/*---停車場初始化---*/
int Init_Stop_car(Stop_car* s)
{
if (s == NULL)
{
return 0;
}
// s->Car_license = ""; //汽車號碼置空
// s->Car_Inbound = 0;
// s->Car_Outbound = 0;
s->next = NULL; //頭插法式初始化
// s->flag = 0;
Stop_car_Num = 0; //停車場初始車數量為零
return 1;
}
/*---便車道初始化---*/
int Init_Lane(Lane* L)
{
L->Car_license = (Elemtype*)malloc(SIZE_INIT_LANE * sizeof(Elemtype));
if (L->Car_license == NULL)
return 0;
L->num = 0;
L->size = SIZE_INIT_LANE;
return 1;
}
/*---車入站(停車站/便車站)---*/
int push_car(Elemtype carNum, int time, Stop_car* s, Lane* L)
{
//當停車場還能容納車
if (Stop_car_Num < MAX)
{
Stop_car* node = (Stop_car*)malloc(sizeof(Stop_car));
if (node == NULL)
{
return 0;
}
node->Car_license = carNum;
node->Car_Inbound = time; //到達時刻
node->flag = 1;
node->next = s->next;
s->next = node;
Stop_car_Num++;
return 1;
}
else
{
if (L->num < SIZE_INIT_LANE)
L->Car_license[L->num++] = carNum;
else
{
L->Car_license[L->num++] = carNum;
L->Car_license = (char*)realloc(L->Car_license, (L->size + INCREASE) * sizeof(char));
if (L->Car_license == NULL)
exit(0);
L->size += INCREASE;
}
return 1;
}
}
/*---車出站(停車站/便車道)---*/
int pull_car(Elemtype carNum, int time, Stop_car* s, Lane* L)
{
float Price; //這裡(計算費用)可以另寫一個函式 ,有點讓出站函式功能不單一了
Stop_car* ss = find_INSTOP(s, carNum);
if (ss != NULL)
{
Stop_car* p = ss->next;
p->Car_Outbound = time;
Price = (p->Car_Outbound - p->Car_Inbound) * PRICE;
ss = p->next;
free(p);
printf("\n出站成功,本次費用為%.3f", Price);
if(L->num>=1)
{
push_car(L->Car_license[0],time,s,L);
L->Car_license++;
L->num--;
}
else
{
return 1;
}
}
else if (ss == NULL)
{
int f = find_Lane(L, carNum);
if (f >= 0)
{
for (int i = f; i < L->num; i++)
{
L->Car_license[i] = L->Car_license[i + 1];
}
L->size--;
return 1;
}
else
{
printf("暫無此車");
return 0;
}
}
else
{
printf("暫無此車");
return 0;
}
}
/*---判斷某輛車是否在停車場---*/
Stop_car* find_INSTOP(Stop_car* s, Elemtype carNum)
{
Stop_car* ss = s;
Stop_car* p = ss->next;
while (p != NULL)
{
if (p->Car_license == carNum)
return ss;
ss = p;
p = p->next;
}
return NULL;
}
/*---判斷車是否在便車道---*/
int find_Lane(Lane* L, Elemtype carNum)
{
Lane* LL = L;
for (int i = 0; i < LL->num; i++)
{
if (LL->Car_license[i] == carNum)
return i;
}
return -1;
}
/*---車站管理選單---*/
void meau(Stop_car* s, Lane* L)
{
int flag;
char ch,ch1;
Elemtype carNum;
int time;
printf("---------------------停車站模擬---------------------\n");
printf("輸入格式(到達/離去,汽車牌照號碼,達到/離去的時刻)\n");
printf("請輸入(A:代表進站 D:代表出站 P:代表結束(結束後顯示狀態))\n");
flag = 1;
while (flag)
{
printf("輸入格式(到達/離去,汽車牌照號碼,達到/離去的時刻)\n");
scanf("%c", &ch);
ch1 = getchar();
switch (ch)
{
case 'A': {
scanf("%c,%d",&carNum,&time);
ch1 = getchar();
if(find_INSTOP(s,carNum)||find_Lane(L,carNum)>=0)
{
printf("該車已近入站\n");
}
else
{
push_car(carNum,time,s,L);
printf("入站成功\n");
}
}; break;
case 'D': {
scanf("%c,%d",&carNum,&time);
ch1 = getchar();
pull_car(carNum, time, s, L);
printf("出站成功\n");
}; break;
case 'P': {
printf("停車站還剩%d個位置,變車道還有%d個人排隊中\n",MAX-Stop_car_Num,L->num);
ch1 = getchar();
}; break;
}
}
}
思路:
初次看題,便車道想用佇列做,但是難於刪除便車道的某一個車,故用了一個動態順序表;
其他的看程式碼吧,對了,那個車站隨意選位置 我沒給位置賦值(賦值很容易實現,但是隨意選位置不太好實現,姑且不給停車站賦值吧)
這個道題,算是對簡單的順序表和連結串列做了個綜合練習;
下面貼一些出現的錯誤和解釋