/**
* 实验题目:
* 停车场管理程序
* 实验目的:
* 深入掌握栈和队列应用的算法设计
* 实验内容:
* 设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。
* 汽车在停车场内按车辆到达时间的先后顺序,依次由南向北排列(大门在最北端,最
* 先到达的第一辆车停放在车场的最南端),若车场内已停满n辆车,则后来的汽车只能
* 在门外的便道即候车场上等候,一旦有车开走,则排在便道上的第一辆车即可开入;
* 当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车
* 开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时
* 必须按它停留的时间长短交纳费用。
* 用栈模拟停车场,用队列模拟车场外的便道,按照从键盘获候车场中的车辆:104取的数据序列进行模拟管理。
* 每一组输入数据包括3个数据项:汽车到达(1)或者离开(2)、汽车牌照号码以及到达或者
* 离开的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车
* 在停车场内或便道上的停车位置;若是车辆离开,则输出汽车在停车场内停留的时间和
* 应交纳的费用(在便道上停留的时间不收费)。注意:栈采用顺序存储结构,队列采用环形
* 队列。
* 还需设一个临时栈,用于临时停放为要给离开的汽车让路而从停车场退出来的汽车,
* 也用顺序结构实现。
* 用户输入的命令有以下5种:
* 1、汽车到达
* 2、汽车离开
* 3、输出停车场中的所有汽车牌号
* 4、输出候车场中的所有汽车牌号
* 5、退出系统
*/
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#define N 3 // 停车场内最多的停车数
#define M 4 // 候车场内最多的停车数入队
#define PRICE 2 // 每单位停车费用
/*---------------------停车场:栈采用顺序存储结构--------------------*/
typedef struct
{
int car_no[N]; // 车牌号
int car_time[N]; // 进场时间
int top; // 栈顶指针
}SqStack; // 声明顺序栈类型
/*------------------------候车场:队列采用环形队列-------------------*/
typedef struct
{
int car_no[M]; // 车牌号
int que_front; // 队头指针
int que_rear; // 队尾指针
}SqQueue; // 声明环形队列类型
/*------------------------栈的运算算法-------------------*/
/*------------------------初始化栈-------------------*/
static void init_stack(SqStack *&s) // 指针的引用
{
s = (SqStack *)malloc(sizeof(SqStack)); // 动态分配存储空间
s->top = -1;
}
/*------------------------判断栈空-------------------*/
static bool stack_empty(SqStack *s)
{
return (s->top == -1);
}
/*------------------------判断栈满-------------------*/
static bool stack_full(SqStack *s)
{
return (s->top == N - 1);
}
/*------------------------压栈-------------------*/
static bool push(SqStack *&s, int car_no, int car_time)
{
if(s->top == N - 1) // 栈满的情况
return false;
s->top++;
s->car_no[s->top] = car_no; // 车牌号
s->car_time[s->top] = car_time; // 进场时间
return true;
}
/*------------------------出栈-------------------*/
static bool pop(SqStack *&s, int &car_no, int &car_time) // 指针的引用
{
if(s->top == -1) // 栈空的情况
return false;
car_no = s->car_no[s->top]; // 提取车牌号
car_time = s->car_time[s->top]; // 提取进场时间
s->top--;
return true;
}
/*------------------------显示栈中元素-------------------*/
static void display_stack(SqStack *s)
{
int i;
for(i = s->top; i >= 0; i--)
printf("%d ", s->car_no[i]);
printf("\n");
}
/*------------------------队列的运算算法-------------------*/
/*------------------------初始化队列-------------------*/
static void init_queue(SqQueue *&q) // 指针的引用
{
q = (SqQueue *)malloc(sizeof(SqQueue)); // 动态分配存储空间
q->que_front = q->que_front = 0;
}
/*------------------------判断队列空-------------------*/
static bool queue_empty(SqQueue *q)
{
return (q->que_front == q->que_rear);
}
/*------------------------判断队列满-------------------*/
static bool queue_full(SqQueue *q)
{
return ((q->que_rear + 1) % M == q->que_front);
}
/*------------------------入队操作-------------------*/
static bool en_queue(SqQueue *&q, int car_no)
{
if((q->que_rear + 1) % M == q->que_front) // 队满
return false;
q->que_rear = (q->que_rear + 1) % M; // 计算队尾指针
q->car_no[q->que_rear] = car_no;
return true;
}
/*------------------------出队操作-------------------*/
static bool de_queue(SqQueue *&q, int &car_no)
{
if(q->que_front == q->que_rear) // 队空的情况
return false;
q->que_front = (q->que_front + 1) % M; // 计算队头指针
car_no = q->car_no[q->que_front]; // 提取车牌号
return true;
}
/*------------------------显示队列中元素-------------------*/
static void display_queue(SqQueue *q)
{
int i;
i = (q->que_front + 1) % M;
printf("%d ", q->car_no[i]);
while((q->que_rear - i + M) % M > 0)
{
i = (i + 1) % M;
printf("%d ", q->car_no[i]);
}
printf("\n");
}
int main(void)
{
int command; // 输入的命令
int i, j; // 循环变量
int e1, e2;
int car_no; // 车牌号
int car_time; // 到达时间
SqStack *st; // 停车场栈
SqStack *tmp_st; // 临时栈
SqQueue *qu; // 候车场队列
init_stack(st);
init_stack(tmp_st);
init_queue(qu);
do
{
printf(">输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):");
scanf("%d", &command);
switch(command)
{
case 1: // 汽车到达
printf(" 车牌号 到达时间:");
scanf("%d %d", &car_no, &car_time);
if(!stack_full(st)) // 停车场不满
{
push(st, car_no, car_time);
printf(" 停车场位置:%d\n", st->top + 1);
}
else // 停车场满
{
if(!queue_full(qu)) // 候车场不满
{
en_queue(qu, car_no);
printf(" 候车场位置:%d\n", qu->que_rear);
}
else
printf(" 候车场已满,不能停车\n");
}
break;
case 2: // 汽车离开
printf(" 车牌号 离开时间:");
scanf("%d %d", &car_no, &car_time);
for(i = 0; i <= st->top && st->car_no[i] != car_no; i++);
if(i > st->top)
printf(" 未找到该编号的汽车\n");
else
{
for(j = i; j <= st->top; j++)
{
pop(st, e1, e2);
push(tmp_st, e1, e2); // 倒车到临时栈tmp_st中
}
pop(st, e1, e2); //该汽车离开
printf(" %d汽车停车费用:%d\n", car_no, (car_time - e2) * PRICE);
while(!stack_empty(tmp_st)) // 将临时栈tmp_st重新回到st中
{
pop(tmp_st, e1, e2);
push(st, e1, e2);
}
if(!queue_empty(qu)) // 队不空时,将队头进栈st
{
de_queue(qu, e1);
push(st, e1, car_time); // 以当前时间开始计费
}
}
break;
case 3: // 显示停车场情况
if(!stack_empty(st))
{
printf(" 停车场中的车辆:"); // 输出停车场中的车辆
display_stack(st);
}
else
printf(" 停车场中无车辆\n");
break;
case 4: // 显示候车场情况
if(!queue_empty(qu))
{
printf(" 候车场中的车辆:"); // 输出候车场中的车辆
display_queue(qu);
}
else
printf(" 候车场中无车辆\n");
break;
case 0: // 退出
if(!stack_empty(st))
{
printf(" 停车场中的车辆:"); // 输出停车场中的车辆
display_stack(st);
}
if(!queue_empty(qu))
{
printf(" 候车场中的车辆:"); // 输出候车场中的车辆
display_queue(qu);
}
break;
default: // 其它情况
printf(" 输入的命令错误\n");
break;
}
}while(command != 0);
return 0;
}
测试结果:
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
车牌号 到达时间:101 1
停车场位置:1
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
车牌号 到达时间:102 2
停车场位置:2
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
车牌号 到达时间:103 3
停车场位置:3
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
车牌号 到达时间:104 4
候车场位置:1
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):3
停车场中的车辆:103 102 101
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):4
候车场中的车辆:104
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):2
车牌号 离开时间:101 6
101汽车停车费用:10
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):3
停车场中的车辆:104 103 102
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):0
停车场中的车辆:104 103 102