编写停车场管理程序
目的:深入掌握栈和队列应用的算法设计。
内容:编写满足以下要求的停车场管理程序exp3-9.cpp。设停车场内只有一个可停n辆汽车的狭长通道,且只有一个大门可供汽车进出。
汽车在停车场内按车辆到达时间的先后顺序依次由南向北排列(大门在最北端,最先到达的第一辆车停放在停车场的最南端),若停车场内已停满n辆车,则后来的汽车只能在门
外的便道(即候车场上)等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进人的车辆必须先退出停车场为它让路,待该辆车开出大门外,其他车辆再按原次序进人停车场,每辆停放在停车场的车在它离开停车场时必须按停留的时间长短交纳费用。整个停车场的示意图如图3.30所示。
代码思路:
/*用栈表示停车场,队列表示停车场外通道;从键盘输入获取的数据序列进行管理。每一组数据包括(1)*汽车到达*,
(2)*汽车离开*。(3)*汽车牌照号码,到达时间,离开时间*
对每组数据进行操作后输出信息为:若是汽车到达,则输出汽车在停车场内*停留时间*,应该缴纳的费用(在队列便道上停
留时间不收费)。
详细代码:
#include<stdio.h>
#include<malloc.h>
#define N 3 //停车场内最多的停车数
#define M 4 //等候通道内最多停车数
#define Price 2 //每单位停车费用
typedef struct
{
int carnum[N]; //停车场内车牌号
int cartime[N]; //进入停车场时间
int top; //栈顶
}SqStack;
typedef struct
{
int carnum[M]; //候车通道内车牌号
int front; //队首
int rear; //队尾
}SqQueue;
//栈的运算函数
void InitStack(SqStack *&s) //初始化栈
{
s = (SqStack *)malloc(sizeof(SqStack));
s->top = -1;
}
bool StackEmpty(SqStack *s) //判断栈空
{
return (s->top == -1);
}
bool StackFull(SqStack *s) //判断栈满
{
return s->top == N - 1;
}
bool Push(SqStack *&s, int e1, int e2) //进栈
{
if (s->top == N - 1) return false; //栈满,溢出
s->top++;
s->carnum[s->top] = e1; // e1为车牌号进栈
s->cartime[s->top] = e2; // e2为进栈时间
return true;
}
bool Pop(SqStack *&s, int &e1, int &e2) //出栈
{
if (s->top == -1) //栈空,出栈失败
return false;
e1 = s->carnum[s->top];
e2 = s->cartime[s->top];
s->top--;
return true; //出栈成功
}
void DispStack(SqStack *s) //取栈顶元素
{
for (int i = s->top; i >= 0; i--) //从栈顶开始,输出车牌号
printf(" %d", s->carnum[i]);
printf("\n");
}
系统使用了栈(SqStack)和队列(SqQueue)两种数据结构来模拟停车场和等候通道的车辆管理。
具体功能如下:
1. 定义了两个结构体:SqStack 和 SqQueue。
- SqStack 结构体用于表示停车场,包含一个数组carnum存储车牌号,一个数组cartime存储车辆进入停车场的时间,以及一个top指针指示当前栈顶位置。
- SqQueue 结构体用于表示等候通道,包含一个数组carnum存储车牌号,以及front和rear指针分别指示队首和队尾的位置。
2. 定义了一系列栈操作函数:
- InitStack:初始化栈,分配内存并设置栈为空。
- StackEmpty:判断栈是否为空。
- StackFull:判断栈是否已满。
- Push:将车牌号e1和进栈时间e2压入栈中。
- Pop:弹出栈顶车辆的车牌号e1和进栈时间e2,并更新栈顶位置。
- DispStack:显示栈内所有车辆的车牌号,从栈顶开始输出。
//以下为队列的运算算法,并完全展示停车场管理系统的全部逻辑
void InitQueue(SqQueue *&q) //初始化队列
{
q = (SqQueue *)malloc(sizeof(SqQueue));
q->front = q->rear = 0; //队空,队首队尾赋值为0
}
bool QueueEmpty(SqQueue *q) //判断队空
{
return (q->front == q->rear);
}
bool QueueFull(SqQueue *q) //判断队满
{
return ((q->rear + 1) % M == q->front);
}
bool enQueue(SqQueue *&q, int e) //入队列
{
if ((q->rear + 1) % M == q->front) //调用队满,返回false
return false;
q->rear = (q->rear + 1) % M; //q指向队尾
q->carnum[q->rear] = e;
return true;
}
bool deQueue(SqQueue *&q, int &e) //出队列
{
if (q->front == q->rear) //如果队空,队溢出
return false;
q->front = (q->front + 1) % M; //队首等于
e = q->carnum[q->front]; //队首的值传入e 车牌号
return true;
}
void DispQueue(SqQueue *q) //输出队列中的元素
{
int i = (q->front + 1) % M; //此时i=0
printf(" %d", q->carnum[i]);
while ((q->rear - i + M) % M > 0)
{
i = (i + 1) % M;
printf(" %d", q->carnum[i]);
}
printf("\n");
}
int main()
{
int comm, i, j;
int num, time; //num 存放车牌号
int e1, e2;
SqStack *st; //栈指针
SqStack *st1; //临时栈指针
SqQueue *qu; //队列指针
InitStack(st); //初始化栈
InitStack(st1);
InitQueue(qu); //初始化队列
do {
printf(">输入指令(1:到达 2:离开 3:查看停车场 4:查看候车场 0:退出 )");
scanf("%d", &comm);
switch (comm)
{
case 1: //汽车到达
printf(" 请输入车牌号 到达时刻:");
scanf("%d%d", &num, &time);
if (!StackFull(st)) //如果停车场不满
{
Push(st, num, time); //入栈,车辆进入停车场
printf(" 停车场位置:%d\n", st->top + 1);
}
else //停车场满
{
if (!QueueFull(qu))
{
enQueue(qu, num);
printf("停车场位置:%d\n", st->top + 1);
printf("候车通道位置:%d\n", qu->rear);
}
else printf("停车场已满,不能停车\n");
}
break;
case 2: //汽车离开
printf(" 请输入汽车车牌号 离开时刻:");
scanf("%d%d", &num, &time);
for (i = 0; i <= st->top && st->carnum[i] != num; i++); //遍历停车场车牌号和输入的车牌号是否能找到
if (i > st->top) //找不到该车车牌
printf("查找不到该位置编号的汽车\n");
else //停车场内找到了
{
for (j = i; j<=st->top; j++) //从找到的位置开始到最后进入停车场的车为止开始遍历
{
Pop(st, e1, e2); //st出停车场到st1中临时停车
Push(st1, e1, e2); //倒车到临时栈st1中
}
Pop(st, e1, e2); //st离开停车场
printf(" %d汽车停车费用为:%d\n", num, (time - e2)*Price);
while (!StackEmpty(st1)) //临时栈st1不空
{
Pop(st1, e1, e2); //st1出栈
Push(st, e1, e2); //st入栈
}
if (!QueueEmpty(qu)) //队不空
{
deQueue(qu, e1); //出队
Push(st, e1, time); //从当前时间开始计费
}
}
break;
case 3: //显示停车场情况
if (!StackEmpty(st))
{
printf(" 停车场中的车辆车牌号为:");
DispStack(st); //输出停车场中的情况
}
else
printf(" 停车场中无车\n");
break;
case 4: //候车通道中的情况
if (!QueueEmpty(qu))
{
printf(" 候车通道中的车辆车牌号为:");
DispQueue(qu);
}
else printf(" 侯车通道的厂中无车辆\n");
break;
case 0: //结束
if (!StackEmpty(st))
{
printf(" 停车场中的车辆车牌号为:");
DispStack(st);
}
else if (!QueueEmpty(qu))
{
printf(" 侯车通道中的车辆车牌号为: ");
DispQueue(qu);
}
break;
default: //其他情况,输入错误
printf(" 输入的命令错误\n");
break;
}
} while (comm != 0); //当输入comm为0时循环结束,否则继续循环操作
//getchar();
return 0;
整个程序设计的目标是通过这些栈和队列的操作,实现对停车场车辆的进出管理,包括停车、取车以及在停车场满时将车辆放入等候通道等功能。
//以下为链接起来的程序
#include<stdio.h>
#include<malloc.h>
#define N 3 //停车场内最多的停车数
#define M 4 //等候通道内最多停车数
#define Price 2 //每单位停车费用
typedef struct
{
int carnum[N]; //停车场内车牌号
int cartime[N]; //进入停车场时间
int top; //栈顶
}SqStack;
typedef struct
{
int carnum[M]; //候车通道内车牌号
int front; //队首
int rear; //队尾
}SqQueue;
//栈的运算函数
void InitStack(SqStack *&s) //初始化栈
{
s = (SqStack *)malloc(sizeof(SqStack));
s->top = -1;
}
bool StackEmpty(SqStack *s) //判断栈空
{
return (s->top == -1);
}
bool StackFull(SqStack *s) //判断栈满
{
return s->top == N - 1;
}
bool Push(SqStack *&s, int e1, int e2) //进栈
{
if (s->top == N - 1) return false; //栈满,溢出
s->top++;
s->carnum[s->top] = e1; // e1为车牌号进栈
s->cartime[s->top] = e2; // e2为进栈时间
return true;
}
bool Pop(SqStack *&s, int &e1, int &e2) //出栈
{
if (s->top == -1) //栈空,出栈失败
return false;
e1 = s->carnum[s->top];
e2 = s->cartime[s->top];
s->top--;
return true; //出栈成功
}
void DispStack(SqStack *s) //取栈顶元素
{
for (int i = s->top; i >= 0; i--) //从栈顶开始,输出车牌号
printf(" %d", s->carnum[i]);
printf("\n");
}
/*************************************分割线*********************************************/
//以下为队列的运算算法
void InitQueue(SqQueue *&q) //初始化队列
{
q = (SqQueue *)malloc(sizeof(SqQueue));
q->front = q->rear = 0; //队空,队首队尾赋值为0
}
bool QueueEmpty(SqQueue *q) //判断队空
{
return (q->front == q->rear);
}
bool QueueFull(SqQueue *q) //判断队满
{
return ((q->rear + 1) % M == q->front);
}
bool enQueue(SqQueue *&q, int e) //入队列
{
if ((q->rear + 1) % M == q->front) //调用队满,返回false
return false;
q->rear = (q->rear + 1) % M; //q指向队尾
q->carnum[q->rear] = e;
return true;
}
bool deQueue(SqQueue *&q, int &e) //出队列
{
if (q->front == q->rear) //如果队空,队溢出
return false;
q->front = (q->front + 1) % M; //队首等于
e = q->carnum[q->front]; //队首的值传入e 车牌号
return true;
}
void DispQueue(SqQueue *q) //输出队列中的元素
{
int i = (q->front + 1) % M; //此时i=0
printf(" %d", q->carnum[i]);
while ((q->rear - i + M) % M > 0)
{
i = (i + 1) % M;
printf(" %d", q->carnum[i]);
}
printf("\n");
}
int main()
{
int comm, i, j;
int num, time; //num 存放车牌号
int e1, e2;
SqStack *st; //栈指针
SqStack *st1; //临时栈指针
SqQueue *qu; //队列指针
InitStack(st); //初始化栈
InitStack(st1);
InitQueue(qu); //初始化队列
do {
printf(">输入指令(1:到达 2:离开 3:查看停车场 4:查看候车场 0:退出 )");
scanf("%d", &comm);
switch (comm)
{
case 1: //汽车到达
printf(" 请输入车牌号 到达时刻:");
scanf("%d%d", &num, &time);
if (!StackFull(st)) //如果停车场不满
{
Push(st, num, time); //入栈,车辆进入停车场
printf(" 停车场位置:%d\n", st->top + 1);
}
else //停车场满
{
if (!QueueFull(qu))
{
enQueue(qu, num);
printf("停车场位置:%d\n", st->top + 1);
printf("候车通道位置:%d\n", qu->rear);
}
else printf("停车场已满,不能停车\n");
}
break;
case 2: //汽车离开
printf(" 请输入汽车车牌号 离开时刻:");
scanf("%d%d", &num, &time);
for (i = 0; i <= st->top && st->carnum[i] != num; i++); //遍历停车场车牌号和输入的车牌号是否能找到
if (i > st->top) //找不到该车车牌
printf("查找不到该位置编号的汽车\n");
else //停车场内找到了
{
for (j = i; j<=st->top; j++) //从找到的位置开始到最后进入停车场的车为止开始遍历
{
Pop(st, e1, e2); //st出停车场到st1中临时停车
Push(st1, e1, e2); //倒车到临时栈st1中
}
Pop(st, e1, e2); //st离开停车场
printf(" %d汽车停车费用为:%d\n", num, (time - e2)*Price);
while (!StackEmpty(st1)) //临时栈st1不空
{
Pop(st1, e1, e2); //st1出栈
Push(st, e1, e2); //st入栈
}
if (!QueueEmpty(qu)) //队不空
{
deQueue(qu, e1); //出队
Push(st, e1, time); //从当前时间开始计费
}
}
break;
case 3: //显示停车场情况
if (!StackEmpty(st))
{
printf(" 停车场中的车辆车牌号为:");
DispStack(st); //输出停车场中的情况
}
else
printf(" 停车场中无车\n");
break;
case 4: //候车通道中的情况
if (!QueueEmpty(qu))
{
printf(" 候车通道中的车辆车牌号为:");
DispQueue(qu);
}
else printf(" 侯车通道的厂中无车辆\n");
break;
case 0: //结束
if (!StackEmpty(st))
{
printf(" 停车场中的车辆车牌号为:");
DispStack(st);
}
else if (!QueueEmpty(qu))
{
printf(" 侯车通道中的车辆车牌号为: ");
DispQueue(qu);
}
break;
default: //其他情况,输入错误
printf(" 输入的命令错误\n");
break;
}
} while (comm != 0); //当输入comm为0时循环结束,否则继续循环操作
//getchar();
return 0;
}