[问题描述]
设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
[基本要求]
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表实现。
[实现提示]
需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。输入数据按到达或离去的时刻有序。栈中每个元素表示一辆汽车,包含两个数据项:汽车的牌照号码和进入停车场的时刻。
车子car信息有车牌号和到达停车场的时间
停车场park为栈,大小为N。
临时让路道tmp为栈,大小为M。
通道line为链队列。
//车子
typedef struct Car{
int num;
int time;
}Car;
//栈
typedef struct stack{
Car *base;
Car *top;
int curlen;
}Park,Tmp;
Park park; //停车场(栈)
Tmp tmp; //临时让路道(栈)
//链队列结点:数据域为车子
typedef struct qnode{
Car car;
struct qnode *next;
}qnode;
//链队列
typedef struct queue{
qnode *front;
qnode *rear;
int curlen;
}Line;
Line line; //通道(链队列)
其次初始化停车场park、临时让路道tmp、通道line,就是分配空间等基本操作。
//初始化停车场park(栈)
void Initpark(){
park.base=(Car *)malloc(sizeof(Car)*N);
park.top=park.base;
park.curlen=0;
}
//初始化临时让路道tmp(栈)
void Inittmp(){
tmp.base=(Car *)malloc(sizeof(Car)*M);
tmp.top=tmp.base;
tmp.curlen=0;
}
//初始化通道line(链队列)
void Initline(){
line.front=(qnode *)malloc(sizeof(qnode));
line.front->next=NULL;
line.rear=line.front;
line.curlen=0;
}
进停车场park、临时让路道tmp、通道line的操作算法,都是简单的入栈和入队操作,如下:
//车子进停车场park(栈)
void Inpark(Car e){
*(park.top)=e;
park.top++;
park.curlen++;
printf("车辆%d停放在停车场第%d个位置.\n",e.num,park.curlen);
}
//车子进通道line(链队列)
void Inline(Car e){
qnode *s=(qnode*)malloc(sizeof(qnode));
s->car=e;
s->next=NULL;
line.rear->next=s;
line.rear=s;
line.curlen++;
printf("车辆停放在通道第%d个位置.\n",line.curlen);
}
//车子进去临时让路道tmp(栈)
void Intmp(Car e){
*(tmp.top)=e;
tmp.top++;
tmp.curlen++;
}
出栈函数和取队头元素,此处出栈函数是park栈和tmp栈所需的操作,取队头元素是为了得到通道上第一辆车。
//出栈操作
void Outstack(stack *s){
s->top--;
s->curlen--;
}
//通道line(链队列)的第一辆车即队头元素
Car Outline(){
qnode *firstqnode=line.front->next;
Car firstcar=firstqnode->car;
line.front->next=firstqnode->next;
line.curlen--;
return firstcar;
}
简单的遍历操作,显示栈里元素和队列元素如下:
void Dispark(){
printf("停车场:\n");
Car *p=park.base;
while(p!=park.top){
printf("车辆:%d\t到达时间:%d\n",p->num,p->time);
p++;
}
}
void Disline(){
printf("通道:\n");
qnode *p=line.front->next;
while(p){
printf("车辆:%d\t到达时间:%d\n",(p->car).num,(p->car).time);
p=p->next;
}
也是较为复杂的操作,即出停车场的操作。
需要先在park栈里找到要出停车场的车子left_car,从park栈栈顶元素逐个弹出到tmp栈里,找到left_car后,从停车场弹出,然后将tmp栈的元素又逐个弹出到park栈,最后取line队列里队头元素,即通道里第一辆车,入park栈。
//车子出停车场park
void Outpark(Car e){
int num=e.num;
int outtime=e.time; //离开时间
Car *c=park.top-1; //栈顶元素
while(c->num!=num&&park.top>park.base){
Intmp(*c); //栈顶元素(车子)进临时让路道
Outstack(&park); //栈顶元素(车子)暂时弹出去
c--;
}
if(park.top==park.base) {
printf("停车场无此车.\n");
}
else{
int spendtime=outtime-(c->time);
printf("收费%d\n",spendtime);
Outstack(&park); //车子出停车场
}
//将所有临时让路道里的车子出tmp栈,并入park栈
while(tmp.curlen>0){
Outstack(&tmp);
Inpark(*(tmp.top));
}
//让通道line里的队头元素(车子)进停车场park
while(park.curlen0){
Car linefirstcar=Outline();
linefirstcar.time=e.time;
Inpark(linefirstcar);
}
}
#include
#include
#define N 3 //停车场park总共位置
#define M 3 //通道line总共位置
//车子
typedef struct Car{
int num;
int time;
}Car;
//栈
typedef struct stack{
Car *base;
Car *top;
int curlen;
}Park,Tmp;
Park park; //停车场(栈)
Tmp tmp; //临时让路道(栈)
//链队列结点:数据域为车子
typedef struct qnode{
Car car;
struct qnode *next;
}qnode;
//链队列
typedef struct queue{
qnode *front;
qnode *rear;
int curlen;
}Line;
Line line; //通道(链队列)
//初始化停车场park(栈)
void Initpark(){
park.base=(Car *)malloc(sizeof(Car)*N);
park.top=park.base;
park.curlen=0;
}
//初始化临时让路道tmp(栈)
void Inittmp(){
tmp.base=(Car *)malloc(sizeof(Car)*M);
tmp.top=tmp.base;
tmp.curlen=0;
}
//初始化通道line(链队列)
void Initline(){
line.front=(qnode *)malloc(sizeof(qnode));
line.front->next=NULL;
line.rear=line.front;
line.curlen=0;
}
//车子进停车场park(栈)
void Inpark(Car e){
*(park.top)=e;
park.top++;
park.curlen++;
printf("车辆%d停放在停车场第%d个位置.\n",e.num,park.curlen);
}
//车子进通道line(链队列)
void Inline(Car e){
qnode *s=(qnode*)malloc(sizeof(qnode));
s->car=e;
s->next=NULL;
line.rear->next=s;
line.rear=s;
line.curlen++;
printf("车辆停放在通道第%d个位置.\n",line.curlen);
}
//车子进去临时让路道tmp(栈)
void Intmp(Car e){
*(tmp.top)=e;
tmp.top++;
tmp.curlen++;
}
//出栈操作
void Outstack(stack *s){
s->top--;
s->curlen--;
}
//通道line(链队列)的第一辆车即队头元素
Car Outline(){
qnode *firstqnode=line.front->next;
Car firstcar=firstqnode->car;
line.front->next=firstqnode->next;
line.curlen--;
return firstcar;
}
//车子出停车场park
void Outpark(Car e){
int num=e.num;
int outtime=e.time; //离开时间
Car *c=park.top-1; //栈顶元素
while(c->num!=num&&park.top>park.base){
Intmp(*c); //栈顶元素(车子)进临时让路道
Outstack(&park); //栈顶元素(车子)暂时弹出去
c--;
}
if(park.top==park.base) {
printf("停车场无此车.\n");
}
else{
int spendtime=outtime-(c->time);
printf("收费%d\n",spendtime);
Outstack(&park); //车子出停车场
}
//将所有临时让路道里的车子出tmp栈,并入park栈
while(tmp.curlen>0){
Outstack(&tmp);
Inpark(*(tmp.top));
}
//让通道line里的队头元素(车子)进停车场park
while(park.curlen0){
Car linefirstcar=Outline();
linefirstcar.time=e.time;
Inpark(linefirstcar);
}
}
void Dispark(){
printf("停车场:\n");
Car *p=park.base;
while(p!=park.top){
printf("车辆:%d\t到达时间:%d\n",p->num,p->time);
p++;
}
}
void Disline(){
printf("通道:\n");
qnode *p=line.front->next;
while(p){
printf("车辆:%d\t到达时间:%d\n",(p->car).num,(p->car).time);
p=p->next;
}
}
int main(){
Initpark();
Inittmp();
Initline();
int flag=0;
while(flag!=99){
printf("1.汽车停放\t");
printf("2.汽车离开\t");
printf("3.查看停车场\t");
printf("4.查看通道\t");
printf("99.退出\n");
printf("请输入:");
scanf("%d",&flag);
switch(flag){
case 1:{
printf("输入车牌号和当前时间:");
Car car;
scanf("%d%d",&car.num,&car.time);
if(park.curlen