C语言实现:设计循环队列(数组实现)

这是Leetcode中的第622题,大家可以做一下:
622.设计循环队列
在这里插入图片描述

一.解题思路:

1.循环?怎么循环呢?

在这里插入图片描述

2.为何要多开一个空间?

在这里插入图片描述
初始状态我们将front和rear都设置为0,此时队列为空
那么可能很多小伙伴会仍然像非循环队列那样让front指向队首元素,rear指向队尾元素的下一个,

入队列:arr[rear]=value;rear++;
出队列:front++;

也就是这样:
中间过程图:此时0,1,2,3,4进入队列
在这里插入图片描述
最终状态
在这里插入图片描述
图中0,1,2,3,4,5,6,7依次进入队列,正好也表示数组的下标
此时队列满了,不过:front=rear
此时front=rear,本该表示队列为空,但是现在队列是满的,那我们应该如何解决这个问题呢?

常见的方法有两种:
1.留一个空位, front和rear重合为空,front在rear前面一个位置为满
2.用一个变量记录队列中元素数量

这里我们采用第一种方法:

3.怎么判空,怎么判满?

在这里插入图片描述

判空:front==rear
判满:(rear+1)%(队列长度)==front

二:本题特殊之处

在这里插入图片描述
所以有了下面的代码:

//取队尾元素的函数
int myCircularQueueRear(MyCircularQueue* obj) {
	//题目要求:如果队列为空,返回-1
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    //rear==0
    if(obj->rear==0)
    {
        return obj->arr[obj->k];
    }
    //rear!=0
    else
    {
        return obj->arr[obj->rear-1];
    }
}

在这里插入图片描述
代码如下:

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    int ret_i=(obj->rear+obj->k)%(obj->k+1);
    return obj->arr[ret_i];
}

三.本题代码(C语言实现)

typedef struct {
    int* arr;
    int front;
    int rear;
    int k;
} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {
    //两次malloc
    MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    cq->arr=(int*)malloc(sizeof(int)*(k+1));
    cq->front=0;
    cq->rear=0;
    cq->k=k;
    return cq;
}
//Front函数和Rear函数要判空和判满,前置声明一下
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    obj->arr[obj->rear]=value;
    obj->rear++;
    //防止假溢出,实现循环,进行取余操作
    obj->rear%=(obj->k+1);
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->front++;
    //防止假溢出,实现循环,进行取余操作
    obj->front%=(obj->k+1);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    //队列为空
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->arr[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    //队列为满
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    int ret_i=(obj->rear+obj->k)%(obj->k+1);
    return obj->arr[ret_i];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front==obj->rear;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1)==obj->front;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    //两次free
    free(obj->arr);
    free(obj);
}

在这里插入图片描述

以上就是循环队列的讲解,希望能对大家有所帮助!

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
好,以下是将队列变为数组的 C 语言代码实现: ```c #include <stdio.h> #include <string.h> #define MAX_N 10 struct Car { char id[10]; int time; }; int main() { int n, head = 0, tail = 0; struct Car park[MAX_N]; // 停车场数组 struct Car wait[MAX_N]; // 等待队列数组 memset(park, 0, sizeof(park)); memset(wait, 0, sizeof(wait)); scanf("%d", &n); while (1) { char op[2]; scanf("%s", op); if (op[0] == 'E') { // 输入结束,输出剩余车辆停留时间并退出程序 for (int i = 0; i < tail; i++) { printf("车辆 %s 在停车场内停留了 %d 分钟。\n", wait[i].id, op[1] - '0' - wait[i].time); } for (int i = 0; i < head; i++) { printf("车辆 %s 在等待队列中等待。\n", park[i].id); } break; } else if (op[0] == 'A') { // 车辆到达 char id[10]; int time; scanf("%s %d", id, &time); if (head < n) { // 停车场未满,将该车辆加入停车场数组 strcpy(park[head].id, id); park[head].time = time; printf("车辆 %s 停在了停车场的第 %d 个位置。\n", id, head + 1); head++; } else { // 停车场已满,将该车辆加入等待队列数组 strcpy(wait[tail].id, id); wait[tail].time = time; printf("车辆 %s 进入了等待队列。\n", id); tail++; } } else if (op[0] == 'D') { // 车辆离开 char id[10]; int time; scanf("%s %d", id, &time); int found = 0; for (int i = 0; i < head; i++) { if (strcmp(park[i].id, id) == 0) { // 在停车场数组中查找该车辆 printf("车辆 %s 在停车场内停留了 %d 分钟。\n", id, time - park[i].time); found = 1; for (int j = i; j < head - 1; j++) { park[j] = park[j + 1]; } head--; break; } } if (!found) { for (int i = 0; i < tail; i++) { if (strcmp(wait[i].id, id) == 0) { // 在等待队列数组中查找该车辆 printf("车辆 %s 在等待队列中等待。\n", id); for (int j = i; j < tail - 1; j++) { wait[j] = wait[j + 1]; } tail--; break; } } } if (tail > 0) { // 如果等待队列数组中有车辆,将等待队列数组中的第一个车辆加入停车场数组 strcpy(park[head].id, wait[0].id); park[head].time = time; printf("车辆 %s 从等待队列中进入了停车场的第 %d 个位置。\n", wait[0].id, head + 1); for (int i = 0; i < tail - 1; i++) { wait[i] = wait[i + 1]; } tail--; head++; } } } return 0; } ``` 这段代码定义了两个结构体数组,一个用来存放停车场信息,一个用来存放等待队列信息。然后在主函数中先输入停车场的容量 n,然后进入一个循环,每次输入一组车辆信息。当输入结束时,输出停车场内剩余车辆的停留时间并退出程序。 如果输入的是车辆到达信息,先判断停车场内是否已经停满了车。如果停满了,则将该车辆加入到等待队列数组中,否则将该车辆加入到停车场数组中,并输出该车辆的停车位置。 如果输入的是车辆离开信息,先在停车场数组中查找该车辆的位置,如果找到了,则计算该车辆停留的时间,并将该车辆从停车场数组中删除。如果在停车场数组中没有找到该车辆,则在等待队列数组中查找该车辆的位置,如果找到了,则将该车辆从等待队列数组中删除。如果等待队列数组中有车辆,将等待队列数组中的第一个车辆加入停车场数组。 最后,如果输入的是结束信息,输出停车场内剩余车辆的停留时间,并清空停车场数组和等待队列数组

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

program-learner

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

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

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

打赏作者

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

抵扣说明:

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

余额充值