单行道停车场问题:栈和队列

问题描述:

某单位停车场共有n个车位,是一个一端封闭的只有一排的狭长通道,车辆只能由左向右依次停放,最右端有一个大门供车辆出入。当车位未满时,车辆可以进入并停在最后一辆车的后面;当车位已满时,车辆需在大门外排队等待,最多可允许 m辆车排队等待。当停车场有车辆离开时,停在后面的车要依次退出让路,待车辆驶出后再按原次序进入,之后门外等待的第一辆车可进入停车场,排队车辆依次前移一个位置。车辆要记入的信息为车牌号。

要求:用栈模拟停车场,用队列模拟排队等待的车辆。实现车辆进入停车场、离开停车场、按车牌号查找车辆位置等功能,并能显示出停车场及等待队列中的全部车辆信息。

代码实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MSIZE 100

typedef struct{
    char **data;
    int top;
    int size;
}Stack;
//结构体定义栈

typedef struct{
    char **data;
    int size;
    int front;
    int rear;
}Queue;
//定义一个队列,顺序存储

void InitStack(Stack &S, int n){
    S.data = (char **)malloc(n*sizeof(char *));
    for(int i = 0; i < n; i++)
    {
        S.data[i] = (char *)malloc(MSIZE*sizeof(char));
    }
    S.top = 0;
    S.size = n;
}
//根据用户自定义的停车场容量n初始化栈

void PushStack(Stack &S){
    char a;
    scanf("%s", S.data[S.top]);
    S.top++;
}
//入栈操作,车进入车库

char *PopStack(Stack &S){
    char *a;
    S.top--;
    a = S.data[S.top];
    return a;
}
//出栈操作,车离开停车场

void PrintStack(Stack &S){
    printf("停车场的车辆:\n");
    if(S.top == 0)
    {
        printf("NONE\n");//停车场没有车输出NONE
    }
    else
    {
        for(int i = S.top-1; i >= 0; i--)
        {
            printf("%s\n", S.data[i]);
        }
    }
}
//打印栈内容,显示停车场内全部车辆信息

void InitQueue(Queue &Q, int m){
    Q.data = (char **)malloc(m*sizeof(char *));
    for(int i = 0; i < m; i++)
    {
        Q.data[i] = (char *)malloc(MSIZE*sizeof(char));
    }
    Q.size = m;
    Q.front = 0;
    Q.rear = 0;
}
//初始化排队等候的车的队列,队列大小m由用户指定

void EnQueue(Queue &Q){
    char a[MSIZE];
    scanf("%s", Q.data[Q.rear]);
    Q.rear++;
}
//入队操作,车辆进入排队

char *OutQueue(Queue &Q){
    char *a;
    a = Q.data[Q.front++];
    return a;
}
//出队操作,车离队进入停车场

void PrintQueue(Queue &Q){
    printf("队列中的车辆:\n");
    if(Q.front-Q.rear == 0)
    {
        printf("NONE\n");//队列为空输出NONE
    }
    else
    {
        for(int i = Q.front; i < Q.rear; i++)
        {
            printf("%s\n", Q.data[i]);
        }
    }
}
//打印队列,输出在排队的所有车辆信息

int Deploy(Stack &S, Queue &Q, int x){
    if(x > S.size + Q.size)//超出容量,程序报错
    {
        printf("输入错误,程序结束!\n");
        return -1;//错误时返回0
    }
    printf("请输依次输入这些车的车牌\n");
    if(x <= S.size)
    {
        for(int i = 0; i < x; i++)
        {
            PushStack(S);
        }
        printf("所有车辆进入停车场\n");
        return 0;
    }
    else
    {
        for(int i = 0; i < S.size; i++)//前n辆车入栈
        {
            PushStack(S);
        }
        for(int i = 0; i < x-S.size; i++)//其余进入队列
        {
            EnQueue(Q);
        }
        printf("前%d辆车进入停车场,其余进入队列等候\n", S.size);
        return 0;
    }
}

int Come(Stack &S, Queue &Q){
            if(S.top == S.size)//先判断停车场有没有满,没满就直接进入停车场
            {
                printf("停车场已满\n");
            }
            else
            {
                printf("请输入车牌号\n");
                PushStack(S);
                printf("车辆停入停车场\n");
                return 0;
            }
            if(Q.front-Q.rear == Q.size)//判断队列是否满,不满则在队列中排队
            {
                printf("队列已满,无法再新增车辆!\n");
            }
            else
            {
                printf("请输入车牌号\n");
                EnQueue(Q);
                printf("车辆进入队列等待\n");
                return 0;
            }
}
//有车辆到来时的操作

void Leave(Stack &S, Queue &Q){
    char a[MSIZE];
    printf("请输入要离开停车场的车牌号\n");
    scanf("%s", a);//获取需要出停车场的车牌
    int flag = 0;//用flag表示离开停车场是否成功
    Stack S1;//新建一个栈暂存需要暂时出停车场的车
    InitStack(S1, S.size);
    int count = 0;//记录出库车的数量
    for(int i = S.top-1; i >= 0; i--)//在栈中查找
    {
        if(strcmp(S.data[i], a) != 0)
        {
            count++;
            strcpy(S1.data[S1.top], PopStack(S));//如果不是指定的车,先出栈,存到暂存栈
            S1.top++;
        }
        else
        {
            flag = 1;
            PopStack(S);//找到指定的车,出栈,结束查找
            printf("这辆车成功离开停车场\n");
            break;
        }
    }
    for(int i = 0; i < count; i++)
    {
        strcpy(S.data[S.top],PopStack(S1));//车从暂存栈回到原来的栈,指定车辆出停车场的操作完成
        S.top++;
    }
    if(flag == 1)
    {
        strcpy(S.data[S.top], OutQueue(Q));//如图有车辆成功离开停车场,则队列里面的第一辆车进入
        S.top++;
        printf("队列中第一辆车进入停车\n");
    }
    else
    {
        printf("这辆车不在停车场中!\n");
    }
}
//指定车辆出库

int Search(Stack &S, Queue &Q){
    char a[MSIZE];
    printf("请输入要查找的车牌号\n");
    scanf("%s", a);
    int where = 0;//用where记录位置
    int flag = 0;//flag表示是否找到
    for(int i = 0; i < S.top; i++)//从车库最里边(左侧)开始遍历查找
    {
        where++;
        if(strcmp(S.data[i], a) == 0)
        {
            flag = 1;
            break;
        }
    }
    if(flag == 1)
    {
        printf("这辆车在停车场从左往右第%d个\n", where);
        return 0;
    }//输出车辆的位置
    where = 0;//where重置为0,开始在队列中查找
    for(int i = Q.front; i <= Q.rear; i++)//从队列头部开始查找
    {
        where++;
        if(strcmp(Q.data[i], a) == 0)
        {
            flag = 1;
            break;
        }
    }
    if(flag == 1)
    {
        printf("这辆车在队列中排第%d个\n", where);
        return 0;
    }//输出车辆的位置
    else
    {
        printf("没有找到\n");
        return 0;
    }
}
//查找车辆

int main(){
    Stack S;
    Queue Q;
    int n, m;//停车场容量为n,队伍长度上限为m
    printf("请输入停车场容量大小\n");
    scanf("%d", &n);
    printf("请输入排队长度上限\n");
    scanf("%d", &m);
    InitStack(S, n);
    InitQueue(Q, m);
    int x;
    printf("请输入需要停车的车辆数(不超过停车场和队伍的容量和)\n");
    scanf("%d", &x);

    if(Deploy(S, Q, x) == -1) return 0;//部署这些车辆的位置,输入错误时Deploy返回值为-1,程序结束

    int option;
    do
    {
        printf("\n接下来你的操作是:\n1.有车到来\n2.有车离开停车场\n3.查看所有车辆\n4.查找指定车辆\n0.结束程序\n");
        scanf("%d", &option);
        printf("\n");
        if(option == 1)
        {
            Come(S, Q);//有车辆到来时,执行函数Come,执行车辆直接进入车库或者是队列,亦或是容量满了无法进入
        }
        else if(option == 2)
        {
            Leave(S, Q);//调用前面封装的Leave函数实现车辆离开停车场
        }
        else if(option == 3)
        {
            PrintStack(S);//打印栈
            PrintQueue(Q);//打印队列
        }
        else if(option == 4)
        {
            Search(S, Q);//在栈和队列中查找,调用前面的Search函数
        }
        else if(option != 0){
            printf("无此选项\n");
        }
    } while (option != 0);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦叮当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值