【数据结构】栈和队列实现停车场管理(c语言)

问题描述

设停车场是一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等待,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在他离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。

基本要求

以栈模拟停车场,以队列模拟车场外的便道,按照以终端读入的输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。对每一组输入数据进行操作后的输出信息为:若车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应该缴纳的费用(在便道上停留的时间不收费)。栈以顺序结构实现,队列以链表结构实现。

测试数据

设n=2,输入数据为:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,4,40),(‘E’,0,0)。其中:'A’表示到达(Arrival);'D’表示离去(Departure);'E’表示输入结束(End)。

代码

根据https://blog.csdn.net/sxhelijian/article/details/48918621改的简版。

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 2 //停车场最大停车量 
#define WAITMAX 10 //便道最大停车量 
#define FEE 1 //每小时停车费用
typedef struct{
	int Car[MAXSIZE];
	int ArriveTime[MAXSIZE];
	int top; 
}SqStack;//停车场
typedef struct{
	int Car[WAITMAX];
	int front, rear;
}SqQueue;//便道
void InitStack(SqStack *&S){
	S = (SqStack *)malloc(sizeof(SqStack));
	S->top = -1;
}//初始化栈 
int IsSqStackEmpty(SqStack *S){
	return(S->top == -1);
}//判断栈是否空 
int IsSqStackFull(SqStack *S){
	return(S->top == MAXSIZE -1);
}//判断栈是否满 
int Push(SqStack *&S, int CarNum, int ArriveTime){
	if(S->top == MAXSIZE - 1)//栈满 
		return 0;
	else{
		S->top++;
		S->Car[S->top] = CarNum;
		S->ArriveTime[S->top] = ArriveTime;
		return 1 ;
	}
}
int Pop(SqStack *&S, int &CarNum, int &ArriveTime){
	if(S->top == -1)//栈空
		return 0; 
	else{
		CarNum = S->Car[S->top];
		ArriveTime = S->ArriveTime[S->top];
		S->top--;//逻辑删除,实际存在,Push可覆盖 
		return 1;
	}
}
void InitQueue(SqQueue *&Q){
	Q = (SqQueue *)malloc(sizeof(SqQueue));
	Q->front = Q->rear =0; 
}//初始化队列 
int IsQueueEmpty(SqQueue *Q){
	return (Q->front == Q->rear);
}//判断队列是否空 
int IsQueueFull(SqQueue *Q){
	return ((Q->rear+1)%WAITMAX == Q->front);
}//判断队列是否满 
int enQueue(SqQueue *&Q, int CarNum){
	if((Q->rear+1)%WAITMAX == Q->front)//队满
		return 0;
	else{
		Q->rear = (Q->rear+1)%WAITMAX;
		Q->Car[Q->rear] = CarNum;
		return 1;
	} 
}
int deQueue(SqQueue *&Q, int &CarNum){
	if(Q->front == Q->rear)//队空 
		return 0;
	else{
		Q->front = (Q->front+1)%WAITMAX;
		CarNum = Q->Car[Q->front];
		return 1; 
	}
}
int main(){
 	int input;//输入指令 
 	int CarNum, ArriveTime;//车牌号,到达时间 
 	int time;//当前时间 
	SqStack *S, *St;//停车场,临时栈 
	SqQueue *Q;//便道 
	InitStack(S);
	InitStack(St);
	InitQueue(Q);
	do{
		printf("请输入指令:'A'表示到达(Arrival);'D'表示离开(Departure);'E'表示输入结束(End)。\n");
		scanf(" %c",&input);
		//存在问题:缓冲区仍有回车在,使得scanf语句未被执行、无法循环 
		//%c前加空格接受缓冲区回车 
		if(input == 'A'){//车辆到达 
			printf("请输入车牌号:\n");
			scanf("%d",&CarNum);
			printf("请输入到达时间:\n");
			scanf("%d",&ArriveTime);
			if(!IsSqStackFull(S)){//当停车场有空时
				Push(S,CarNum,ArriveTime);
				printf("车牌号为%d的车辆已成功于%d时到达%d号停车位。\n",CarNum,ArriveTime,S->top+1); 
			}else{//当停车场满时
				if(!IsQueueFull(Q)){//当便道有空时 
					enQueue(Q,CarNum);
					printf("车牌号为%d的车辆已成功停在便道候车。当前候车位为%d。\n",CarNum,Q->rear);
				} else{//当便道满时
					printf("便道已满,无法停车。\n"); 
				}
			}
		}else if(input == 'D'){//车辆离开 
			printf("请输入车牌号:\n");
			scanf("%d",&CarNum); 
			printf("请输入当前时间:\n");
			scanf("%d",&time);
			int i;
			for( i = 0; i <= S->top && S->Car[i] != CarNum; i++);//寻找该车 
			if(i > S->top){ 
				printf("未找到车牌号为%d的车。\n",CarNum);
			}else{
				int j = S->top - i;//需要出栈的车的数量 
				for(int k = 0; k<j; k++){//将出栈车辆停到临时栈
					Pop(S,CarNum,ArriveTime);
					Push(St,CarNum,ArriveTime); 
				}
				Pop(S,CarNum,ArriveTime);//指定车辆离开
				printf("车牌号为%d的车停车时间为%d,应缴纳费用为%d。\n",CarNum,time-ArriveTime,(time-ArriveTime)*FEE); 
				while(!IsSqStackEmpty(St)){//当临时栈不为空,将出栈车辆重新停回停车场 
					Pop(St,CarNum,ArriveTime);
					Push(S,CarNum,ArriveTime);
				}
				if(!IsQueueEmpty(Q)){//当便道有车时,将第一辆车停入停车场 
					deQueue(Q,CarNum);
					Push(S,CarNum,time);
					printf("车牌号为%d的车辆已成功于%d时到达%d号停车位。\n",CarNum,time,S->top+1); 
				} 
			}
		}else if(input == 'E'){
			printf("输入结束。");
		}else{
			printf("输入错误,请重新输入。\n"); 
		}
	}while(input != 'E');
	return 0;
}

运行结果

在这里插入图片描述在这里插入图片描述

  • 12
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值