参照教学章节的教学视频,完成下面的实验 设停车场是一个可停放n辆车的狭长通道,且只有一个大门可供汽车进出。在停车场内,汽车按到达的先后次序,由北向南依次排列(假设大门在最南端)。若车场内已停满n辆车,则后来的汽车需在门外的便道上等候,当有车开走时,便道上的第一辆车即可开入。当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门后,其他车辆再按原次序返回车场。每辆车离开停车场时,应按其停留时间的长短交费(在便道上停留的时间不收费),示意图如下。
COMMON.C
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h> //获取系统时间的相关库
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
SEQSTACK.H
#include"common.h"
#define Stack_Size 50 //设顺序栈中最大元素个数为50,即停车场最多能容纳车
typedef struct //自定义结构类型,用来存放车辆信息,队列和栈都有使用,所以放在common.h中
{
int CarNo; //车牌号
time_t Itime; //进场时间
time_t Otime; //出场时间
}StackElementType;
//栈结构定义
typedef struct
{
StackElementType elem[Stack_Size]; //栈中存放数据元素的一维数组
int top; //栈顶指示器,-1表示空栈
}SeqStack;
//栈的初始化
void InitStack(SeqStack S);
//进栈
int Push(SeqStackS,StackElementType x);
//出栈
int Pop(SeqStack*S,StackElementType x);
//读取栈顶元素
int GetTop(SeqStackS,StackElementType *x);
//是否满栈
int FullStack(SeqStack *S);
//是否空栈
int EmptyStack(SeqStack *S);
SEQQUEUE.H
#include"common.h"
#define MAXSIZE 50 //队列的最大长度
typedef struct //自定义结构类型,用来存放车辆信息,队列和栈都有使用,所以放在common.h中
{
int CarNo; //车牌号
time_t Itime; //进场时间
time_t Otime; //出场时间
}QueueElementType;
//队列的定义,用于待停临时候停区
typedef struct
{
QueueElementType element[MAXSIZE]; //队列的元素空间
int front; //头指示器
int rear; //尾指示器
}SeqQueue;
//初始化操作
void InitQueue(SeqQueue Q)
{
Q->front=Q->rear=0; //将Q初始化为一个空的循环队列
}
//入队操作,将元素x入队
int EnterQueue(SeqQueue*Q,QueueElementType x)
{
if((Q->rear+1)%MAXSIZE==Q->front) //队列已经满了
return(FALSE);
Q->element[Q->rear]=x;
Q->rear=(Q->rear+1)%MAXSIZE; //重新设置队尾指示器
return(TRUE);
}
//出队操作,删除队列的队头元素,用x返回其值
int DeleteQueue(SeqQueue *Q,QueueElementType *x)
{
if(Q->front==Q->rear) //如果队列为空
return(FALSE);
*x=Q->element[Q->front];
Q->front=(Q->front+1)%MAXSIZE; //重新设置队头指针
return(TRUE);
}
//或取队列的队头元素,用x返回其值
int GetHead(SeqQueue *Q,QueueElementType *x)
{
if(Q->front==Q->rear) //队列为空
return(FALSE);
*x=Q->element[Q->front]; //返回值到x
return(TRUE);
}
//判断队列是否为空
int IsEmpty(SeqQueue *Q)
{
if(Q->front==Q->rear) //队列为空
return(TRUE);
else
return(FALSE);
}
SEQSTACK.C
#include"seqstack.h"
//栈的初始化
void InitStack(SeqStack *S)
{
S->top=-1; //栈顶指针指向-1,表示空栈
}
//进栈,车辆进入停车场
int Push(SeqStack *S,StackElementType x)
{
//如果栈满,返回FALSE
if(S->top==Stack_Size-1)
return FALSE;
S->top++; //栈顶指针上移
S->elem[S->top]=x;
return TRUE;
}
//出栈:车辆离场
int Pop(SeqStack*S,StackElementType *x)
{
//如果栈空,返回FALSE
if(S->top==-1)
return FALSE;
*x=S->elem[S->top]; //栈顶元素赋值给x
S->top–; //栈顶指针下移
return TRUE;
}
//读取栈顶元素
int GetTop(SeqStack*S,StackElementType *x)
{
//如果栈空,返回FALSE
if(S->top==-1)
return FALSE;
*x=S->elem[S->top]; //栈满
return TRUE;
}
//是否满栈
int FullStack(SeqStack *S)
{
if(S->top+1==Stack_Size) //栈满
return TRUE;
else
return FALSE;
}
//是否空栈
int EmptyStack(SeqStack *S)
{
if(S->top==-1) //栈为空
return TRUE;
else
return FALSE;
}
MAIN.C
#include"seqstack.h" //栈的算法
#include"seqqueue.h" //队列的算法
int main()
{
int op=1; //操作控制命令
float money=0; //计算停车费,每秒0.5元
time_t t; //系统定义的时间类型,单位是秒
int cNo; //车牌号
StackElementType car; //栈中存放车辆信息数据
QueueElementType carQ; //队列中存放车辆信息,候车时
SeqStack Park,TemPark; //分别表示停车场和临时挪车停车场
InitStack(&Park); //栈初始化
InitStack(&TemPark);
SeqQueue WaitPark; //待停区队列
InitQueue(&WaitPark); //队列初始化
while(op!=0) //循环操作指令,当输入0时退出
{
printf("*欢迎使用停车管理系统,请输入你的操作:\
\n*1.车辆进场\n*2.车辆出场\n*0.退出系统\n*请输入对应操作的数字:\n");
scanf("%d",&op);
if(op==1) //进场操作
{
//车辆进场时获取车辆信息
printf("请输入车牌号:");
scanf("%d",&cNo);
if(FullStack(&Park)) //如果停车场已满,则进入待停区
{
carQ.CarNo=cNo;
EnterQueue(&WaitPark,carQ); //入队,进入待停区
printf("车辆:%d进入待停区.\n",cNo);
}
else //停车场未满
{
car.CarNo=cNo;
time(&t); //获取当前时间,单位是秒
car.Itime=t; //将进场时间存入
//进场即进栈
if(Push(&Park,car)) //如果进场成功
printf("车辆,%d进场:\n",cNo);
}
}
if(op==2) //2车辆出场操作
{
//获取要出场车辆牌号
printf("请输入车牌号:");
scanf("%d",&cNo);
int find=0; //标记变量,0表示未找到对应车牌车辆,1表示找到对应车辆
while(!EmptyStack(&Park)&&!find) //如果有停车辆且没找到车,就执行操作
{
//从停车场栈顶开始查找车牌,不是对应车辆就把车辆出栈,就入挪车栈
if(Pop(&Park,&car)) //停车场最外面的车辆出场
{
if(car.CarNo!=cNo) //牌号不匹配,出栈的车辆进入挪车栈,则继续查找此车牌
{
if(Push(&TemPark,car)) //如果成功进入挪车区
printf("车辆:%d进入挪车区.\n",car.CarNo);
else
printf("车辆:%d进入挪车区失败.\n",car.CarNo);
}
else //如果查询到车牌,则车辆出场,待停区如果有车辆则进场一辆
{
find=1; //找到车辆,不再找车
//车辆出场
time(&t); //获取系统时间(单位是秒)
car.Otime=t; //获取车辆出场时间
money=(car.Otime-car.Itime)*0.5; //计算停车费,每秒0.5元
printf("车辆:%d出场,停车费:%.1f元.\n",cNo,money);
//挪车区车辆再次进入停车区
while(Pop(&TemPark,&car)) //当挪车区不为空时,一直出栈
{
if(Push(&Park,car)) //车辆重新进入停车场
printf("车辆:%d重新进入停车场.\n",car.CarNo);
}
//此时有空一位,待停区有车则进场
if(!IsEmpty(&WaitPark)) //如果待停区有车,则出队一两车,然后进入停车场
{
DeleteQueue(&WaitPark,&carQ); //出队
car.CarNo=carQ.CarNo;
time(&t); //获取当前时间,单位是秒
car.Itime=t; //将进场时间存入
if(Push(&Park,car)) //如果进场成功
printf("车辆:%d自待停区进场.\n",cNo);
}
}
}
}
if(find==0) //如果始终没有找到要出场的车牌号,则所有车辆在挪车区,需要回停车位
{
printf("没有找到牌号:%d车辆.\n",cNo);
while(Pop(&TemPark,&car)) //当挪车区不为空时,一直出栈
{
if(Push(&Park,car)) //车辆重新进入停车场
printf("车辆:%d重新进入停车场.\n",car.CarNo);
}
}
}
}
return 0;
}