设停车场内只有一个可停放几量汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已经停满几量汽车,则后来的汽车只能在门外的便道上等候,一旦停车场内有车开走,则排在便道上的第一辆汽车即可开入;当停车场内某车辆要离开时,由于停车场是狭长的通道,在它之后开入车场的车辆必须先退出车场为它让路,待该车辆开出大门外后,为它让路的车辆再按原次序进入车场。在这里假设汽车不能从便道上开走。试设计一个停车场管理程序(这里只是一个假想的停车场管理,并不代表实际的停车场管理)。
根据题意及生活常识,可以知道一个车号只能对应一辆汽车,在停车场与便道内不会同时出现多个相同车号的车辆。当执行汽车离开停车场的操作时,注意判断停车场内是否有对应车辆存在。由于便道队列内车辆的目的就是要进入停车场,故不设计便道内车辆离开便道的操作。
主函数基本思路如下:
- 初始化停车场栈和便道队列。
- 通过循环读取用户的命令和车号。
- 如果命令是1(进入停车场),则检查停车场栈是否已满:
- 如果停车场栈未满,检查停车场中是否已经存在相同车号的车辆:
- 如果停车场中存在相同车号的车辆,不进行其他操作,输出提示信息。
- 如果停车场中不存在相同车号的车辆,将该车辆入栈,输出提示信息。
- 如果停车场栈已满,检查停车场中是否已经存在相同车号的车辆:
- 如果停车场中不存在相同车号的车辆,检查便道队列中是否存在相同车号的车辆:
- 如果便道队列中也不存在相同车号的车辆,将车辆入便道队列等候,并输出提示信息。
- 如果便道队列中存在相同车号的车辆,输出提示信息。
- 如果停车场中存在相同车号的车辆,输出提示信息。
- 如果停车场中不存在相同车号的车辆,检查便道队列中是否存在相同车号的车辆:
- 如果停车场栈未满,检查停车场中是否已经存在相同车号的车辆:
- 如果命令是2(离开停车场),则查找停车场栈中是否存在要离开的车辆:
- 如果找到要离开的车辆:将其出栈,并输出提示信息。
- 如果未找到要离开的车:输出提示信息。
- 如果便道队列不为空,将队头车辆出队列,并将其入栈到停车场,输出提示信息。
5.输出停车场栈和便道队列中车辆的停放情况。
6.重复执行步骤2到步骤5,直到用户输入负数或其他非法命令值退出循环。
#include <stdio.h>
#include <stdlib.h>
// 停车场规模大小
#define stacksize 10
// 定义停车场栈的数据结构
typedef struct sqstack
{
int data[stacksize];
int top;
} SqStackTp;
// 定义便道队列的数据结构
typedef struct linked_queue
{
int data;
struct linked_queue *next;
} LqueueTp;
// 定义队列的数据结构
typedef struct
{
LqueueTp *front, *rear;
} QueptrTp;
// 初始化停车场栈
void InitStack(SqStackTp *s)
{
s->top = -1;
}
// 判断停车场栈是否为空
int StackEmpty(SqStackTp *s)
{
return (s->top == -1);
}
// 判断停车场栈是否已满
int StackFull(SqStackTp *s)
{
return (s->top == stacksize - 1);
}
// 停车场栈的入栈操作
int Push(SqStackTp *s, int carNumber)
{
// 检查停车场是否已经存在相同车号的车辆
for (int i = 0; i <= s->top; i++)
{
if (s->data[i] == carNumber)
{
printf("停车场中已经存在车号为 %d 的车辆\n", carNumber);
return 0;
}
}
s->data[++(s->top)] = carNumber;
return 1;
}
// 停车场栈的出栈操作
int Pop(SqStackTp *s)
{
return s->data[(s->top)--];
}
// 初始化便道队列
void InitQueue(QueptrTp *queue)
{
queue->front = queue->rear = NULL;
}
// 判断便道队列是否为空
int QueueEmpty(QueptrTp *queue)
{
return (queue->front == NULL);
}
// 便道队列的入队列操作
void Enqueue(QueptrTp *queue, int carNumber)
{
// 创建新结点
LqueueTp *newNode = (LqueueTp *)malloc(sizeof(LqueueTp));
newNode->data = carNumber;
newNode->next = NULL;
if (QueueEmpty(queue))
{
// 队列为空,直接将新结点设置为队头和队尾
queue->front = queue->rear = newNode;
}
else
{
// 队列不为空,将新结点链接到队列尾结点的后面,更新队列尾指针为新结点
queue->rear->next = newNode;
queue->rear = newNode;
}
}
// 便道队列的出队列操作
int Dequeue(QueptrTp *queue)
{
if (QueueEmpty(queue))
{
printf("便道队列已经没有车辆了!\n");
return -1;
}
LqueueTp *frontNode = queue->front;
int carNumber = frontNode->data;
if (queue->front == queue->rear)
{
// 队列中只有一个结点,将队头和队尾都置为空
queue->front = queue->rear = NULL;
}
else
{
// 队列中有多个结点,将队头指针向后移动一个结点
queue->front = queue->front->next;
}
free(frontNode); // 释放出队的结点内存
return carNumber;
}
int main()
{
SqStackTp parkingStack;
QueptrTp waitingQueue;
int command, carNumber;
InitStack(&parkingStack); // 初始化停车场栈
InitQueue(&waitingQueue); // 初始化便道队列
while (1)
{
printf("\n请输入命令和车号(命令:1表示进入停车场,2表示离开停车场):");
scanf("%d %d", &command, &carNumber); // 输入命令和车号
if (command == 1) // 进入停车场
{
if (!StackFull(&parkingStack)) // 停车场栈未满
{
int flag = Push(&parkingStack, carNumber); // 车辆进入停车场
if (flag)
printf("汽车 %d 进入停车场\n", carNumber);
}
else
{
// 在停车场满的情况下,检查停车场中是否已经存在相同车号的车辆
int flag2 = 0; int flag3 = 0;
for (int i = 0; i <= parkingStack.top; i++)
{
if (parkingStack.data[i] == carNumber)
{
printf("停车场中已经存在车号为 %d 的车辆\n", carNumber);
flag2 = 1;
}
}
// 停车场中不存在相同车号的车辆,检查便道队列中是否存在相同车号的车辆
if ((!flag2) && (!QueueEmpty(&waitingQueue)))
{
LqueueTp *current = waitingQueue.front;
while (current != NULL)
{
if (current->data == carNumber)
{
flag3 = 1;
break;
}
current = current->next;
}
}
// 停车场已满,且停车场与便道队列内均没有相同车号的车辆
if (!flag2 && !flag3)
{
Enqueue(&waitingQueue, carNumber); // 车辆进入便道队列等候
printf("停车场已经没有空位,汽车 %d 进入便道队列等候\n", carNumber);
}
// 停车场已满,停车场内无相同车号的车辆,但便道队列中有相同车号的车辆
if (!flag2 && flag3)
{
printf("汽车 %d 已在便道队列中等候\n", carNumber);
}
}
}
else if (command == 2) // 离开停车场
{
int found = 0; // 是否找到要离开的车辆
// 使用临时栈暂存车辆
SqStackTp tempStack;
InitStack(&tempStack);
while (!StackEmpty(&parkingStack))
{
int temp = Pop(&parkingStack); // 出栈车辆
if (temp == carNumber) // 找到要离开的车辆
{
found = 1;
break; // 跳过将该车辆入栈到临时栈的操作
}
Push(&tempStack, temp); // 将车辆入栈到临时栈
}
// 将临时栈中的车辆重新入栈到停车场
while (!StackEmpty(&tempStack))
{
int temp = Pop(&tempStack);
Push(&parkingStack, temp);
}
if (found)
{
printf("汽车 %d 离开停车场\n", carNumber);
if (!QueueEmpty(&waitingQueue))
{
// 便道队列不为空,取出队头车辆进入停车场
int waitingCar = Dequeue(&waitingQueue);
Push(&parkingStack, waitingCar);
printf("汽车 %d 从便道队列进入停车场\n", waitingCar);
}
}
else
{
printf("停车场中没有汽车 %d\n", carNumber);
}
}
else
{
printf("退出系统。感谢您的使用,谢谢!\n");
break; // 输入命令为负数或其他非法值,退出循环
}
//每次执行完命令后,查看停车场与便道内车辆的停放情况
printf("停车场状态:");
if (StackEmpty(&parkingStack))
{
printf("空");
}
else
{
for (int i = 0; i <= parkingStack.top; i++)
{
printf("%d ", parkingStack.data[i]);
}
}
printf("\n便道队列状态:");
if (QueueEmpty(&waitingQueue))
{
printf("空");
}
else
{
LqueueTp *current = waitingQueue.front;
while (current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
}
printf("\n\n");
}
return 0;
}