每日一题(设计循环队列)

每日一题(设计循环队列)

622. 设计循环队列 - 力扣(LeetCode)

1.题意解读

本题只能为队列开辟k个单位空间,并且只能利用这几个空间进行数据的存储。

思路 :本题使用数组来实现队列是比较方便的,首先定义两个变量:front和rear变量。分别用于记录队头和队尾。一开始初始化时让front和rear都指向数组的第一个位置,存储数据时 ,按着下图的方式,向rear下标处存储数据,存储成功之后rear自加1,也就是意味着rear始终指向的当前队尾元素的下一个位置。

分析假设k的值是5,那么本来应该就是开辟5个空间。但是我用的这种方法需要多开辟一个单位的空间 。为什么呢?假若我们开辟的是5的单位的空间,那么当存满了k个数据之后,此时的rear和front就都指向了数组中的第一个元素。那么请仔细想想,在初始化的时候我们也将rear和front也初始化为了0,也指向了数组中的第一个元素。那么在这两种情况下,front和rear都指向了数组的第一个元素,但是队列中的元素个数却是大不相同,无法将队列为满和队列为空进行分开。为了避免这种问题的发生,这里多开辟一个空间,当rear下标的下一个位置是front时,此时队列中存储了k个元素 ,也就说明了队列已满,那么同时判断队列为空就很方便了。只要rear与front相等时,队列就为空。

删除队头元素:删除队头的元素就只需要将front++即可。

注意:

  • 当遇到了非常规情况时:rear到了队尾需要循环到队头时则只需要执行语句 rear++;rear %= k+1;这两条语句即可。针对front到达队尾需要到达队头的情况也同样适用的。
  • 当需要获取队尾的元素时 ,实际上获取的是rear的前一个下标处的值,需要访问rear-1下标处的值,但是假若此时的rear的值是0,那么此时需要特判以下,假如rear的值是0时,直接访问k下标处的值即可。rear的值不为0时,只需要正常访问rear-1下标处的元素即可。

代码实现:

c 复制代码
typedef struct {
    int* a;
    int front;
    int rear;
    int k;
} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue*  obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = (int*)malloc(sizeof(int)*(k+1));
    obj->front = 0;
    obj->rear = 0;
    obj->k = k;
    return obj;
}

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

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

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    assert(obj);
    if(!myCircularQueueIsFull(obj))//未满
    {
        obj->a[obj->rear] = value;
        obj->rear++;
        obj->rear %= (obj->k+1);
        return true;
    }
    return false;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    if(!myCircularQueueIsEmpty(obj))//非空
    {
        obj->front++;
        obj->front %=obj->k+1;
        return true;
    }
    return false;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
        assert(obj);
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    if(obj->rear == 0)
        return obj->a[obj->k];
    else
    {
         return obj->a[obj->rear-1];
    }
}

void myCircularQueueFree(MyCircularQueue* obj) {
    assert(obj);
    free(obj->a);
    free(obj);
    obj=NULL;
}

完结

设计循环队列的分析就到这里啦,若有不足,欢迎评论区指正,下期见!

相关推荐
吾日三省吾码31 分钟前
JVM 性能调优
java
stm 学习ing36 分钟前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
LNTON羚通1 小时前
摄像机视频分析软件下载LiteAIServer视频智能分析平台玩手机打电话检测算法技术的实现
算法·目标检测·音视频·监控·视频监控
湫ccc2 小时前
《Python基础》之字符串格式化输出
开发语言·python
弗拉唐2 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
mqiqe2 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin2 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python