Leetcode刷题之设计循环队列(C语言版)

Leetcode刷题之设计循环队列(C语言版)

  • 一、题目描述
  • 二、题目示例
  • 三、题目解析
    • Ⅰ、typedef struct
    • Ⅱ、MyCircularQueue* myCircularQueueCreate(int k)
    • Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)
    • Ⅳ、bool myCircularQueueIsFull(MyCircularQueue* obj)
    • Ⅴ、bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
    • Ⅵ、bool myCircularQueueDeQueue(MyCircularQueue* obj)
    • Ⅶ、int myCircularQueueFront(MyCircularQueue* obj)
    • Ⅷ、int myCircularQueueRear(MyCircularQueue* obj)
    • Ⅸ、void myCircularQueueFree(MyCircularQueue* obj)
  • 四、完整代码:

622、设计循环队列

一、题目描述

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。你的实现应该支持如下操作:

①、MyCircularQueue(k): 构造器,设置队列长度为 k 。
②、  Front: 从队首获取元素。如果队列为空,返回 -1 。
③、Rear: 获取队尾元素。如果队列为空,返回 -1 。
④、enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
⑤、deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
⑥、isEmpty(): 检查循环队列是否为空。
⑦、isFull(): 检查循环队列是否已满。

二、题目示例

在这里插入图片描述
在这里插入图片描述

三、题目解析

首先本题我们可以采用两种方法解决,分别是数组和链表。在此,我采用数组的方法为大家解决本道题。大家觉得,上图的环形队列,最多可以存放几个数据呢?我想答案应该是7个or8个。我们从下图不难发现判断循环队列是否为空,我们就可以看frontrear是否相等。

在这里插入图片描述
但是当我们存放8个数据的时候,结果表示如下图所示:
在这里插入图片描述
此时的frontrear也相等,所以无法判断此时的循环队列是为满还是为空的状态。当然我们也可以定义一个size来记录此时的循环队列所存放的数据个数。但是我认为我们可以设定存放7个数据时,循环队列已达到为满的状态。结果如下:
在这里插入图片描述
此时我们可以用rear+1=front来判断循环队列是否达到存满的状态。接下来我们便正式开始本题目的讲解:

Ⅰ、typedef struct

首先在匿名结构体中需要定义4个成员变量,分别是front,rear,*a和k。

typedef struct 
{int front;//前面的int rear;//后面的int k;//存放数据的个数int *a;//数组
} MyCircularQueue;

Ⅱ、MyCircularQueue* myCircularQueueCreate(int k)

这个接口主要是对于刚才的结构体进行初始化,首先利用malloc函数对obj开辟一定的空间。对obj开辟好空间之后,我们就可以对obj中的对象进行一定的初始化。这里需要注意的是我们为数组a开辟的空间是K+1个,因为我们需要利用rear+1=front来判断循环队列是否达到存满的状态。初始化的代码如下:

MyCircularQueue* myCircularQueueCreate(int k) //初始化及开辟空间
{MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a= (int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;   
}

Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)

该接口的目的是判断循环队列是否处于空的状态,前文提到我们可以利用front是否等于rear来判断循环队列是否为空。代码如下:

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

Ⅳ、bool myCircularQueueIsFull(MyCircularQueue* obj)

前文提到我们可以用rear+1是否等于front来判断循环队列是否处于满的状态。但是这种方法也有一种弊端,那就是:
rear+1等于6时,会产生数组越界问题,所以我们可以采用取余的方法来避免这一问题,(rear+1)%(k+1)==front来判断数组是否存储数据已满。
在这里插入图片描述

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

Ⅴ、bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)

向循环队列插入一个元素。如果成功插入则返回真。,这个接口首先要想到的是如果队列已经满了,则不能继续插入,所以先判断是否已满,如果满了就返回false。
接下来便是插入元素,这里需要注意的是我们需要依旧采用取余数的方法让队列循环起来,即:rear = rear % (k + 1)

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

Ⅵ、bool myCircularQueueDeQueue(MyCircularQueue* obj)

从循环队列中删除一个元素。如果成功删除则返回真。这个接口首先要想到的是如果队列为空了,则不能继续删除,所以先判断是否为空,如果为空就返回false。接下来就是删除操作,删除操作很简单,就是让==front++==即可,但是需要注意的是应当取余数避免越界:front = front % (k + 1)

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

Ⅶ、int myCircularQueueFront(MyCircularQueue* obj)

从队首获取元素。如果队列为空,返回 -1 。这个接口比较简单容易实现

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

Ⅷ、int myCircularQueueRear(MyCircularQueue* obj)

获取队尾元素。如果队列为空,返回 -1 。这里需要注意的是,当处在下图所示的情况时,如果强行获取rear的前一个位置可能会产生数组越界问题。所以我们需要采用取余数的方式来解决:rear+k%=(k+1)
在这里插入图片描述

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

Ⅸ、void myCircularQueueFree(MyCircularQueue* obj)

free需要注意的是首先要释放数组申请的内存空间,其次才是obj申请的内存空间。

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

四、完整代码:

typedef struct 
{int front;int rear;int k;//存放数据的个数int *a;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) //初始化及开辟空间
{MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->a= (int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;   
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj){return obj->front==obj->rear;}bool myCircularQueueIsFull(MyCircularQueue* obj) 
{return (obj->rear+1)%(obj->k+1)==obj->front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{if(myCircularQueueIsFull(obj)){return false;}obj->a[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->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj)
{if(myCircularQueueIsEmpty(obj)){return -1;}    return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/225782.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3-admin-template 导入模板功能

先看效果&#xff1a; 直接上代码&#xff1a; 1.绑定事件&#xff1a; <el-button type"primary" click"templates">模板导入</el-button> 2.写结构样式 <!-- 模板导入 --><el-dialog v-model"Statusimprot" title&quo…

2023年通过已经认证的微信公众号注册微信小程序

登录已经认证的微信公众号 注册完成后&#xff0c;打开微信公众平台的网址&#xff0c;用账号密码的方式登录

与 PCIe 相比,CXL为何低延迟高带宽?

文章目录 前言1. LatencyPCIE 生产者消费则模型结论Flit 包PCIE/CXL.ioCXL.cace & .mem总结 2. BandWidth常见开销CXL.IO Link efficiencyPCIe Link efficiencyCXL.IO bandwidthCXL.mem/.cache bandwidth 参考 前言 CXL 规范里没有具体描述与PCIe 相比低延时高带宽的原因&…

视频文案怎么写,媒介盒子支招

近几年短视频成为风口&#xff0c;各行各业都想分一杯羹&#xff0c;但是一头热的你&#xff0c;是否知道短视频的相关文案怎么写呢?正所谓兵马未动&#xff0c;文案先行&#xff0c;一个合适的文案是上热门的秘密武器&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;视频…

【技术干货】宇视IPC音频问题解决步骤

近期技术人员从宇视官网下载sdk进行二次开发时&#xff0c;在启动实时直播&#xff0c;并通过回调函数拿到流数据&#xff0c;发现没有音频流数据。 通过下面的数据发现&#xff0c;codeType此字段一直是28&#xff0c;代表的是H.264数据&#xff0c;但未没发现有音频的数据包…

51单片机项目(16)——基于51单片机的水箱冷却系统

1.项目背景 汽车水箱又称散热器&#xff0c;是汽车冷却系统中主要机件&#xff1b;其功用是散发热量&#xff0c;冷却水在水套中吸收热量&#xff0c;流到散热器后将热量散去&#xff0c;再回到水套内而循环不断。从而达到散热调温的效果。它还是汽车发动机的重要组成部分。 汽…

docker 安装elasticsearch集群

准备工作 docker 安装好&#xff0c;docker compose 安装好编辑好docker-compose.yml文件&#xff08;本文会提供&#xff09;生成elastic-certificates.p12密钥&#xff0c;与docker-compose文件在同一个目录&#xff08;本文会介绍生成方式&#xff09;准备elasticsearch配置…

虚幻学习笔记5—UI预设体制作

一、前言 本文使用的虚幻引擎5.3.2&#xff0c;在unity中有预设体的概念&#xff0c;可以将一个组合型的物体或UI制作成预设体&#xff0c;方便后续可以快速制作更多元的内容和复用。虚幻本身没有这个概念&#xff0c;但是要实现类似的效果其&#xff0c;故此我引用了这个概念。…

iOS-打包上架构建版本一直不出现/正在处理/自动消失

iOS开发过程中&#xff0c;打包上架苹果审核是一个不可或缺的环节。说实话&#xff0c;这个问题我遇见两次了&#xff0c;为了让自己长点记性&#xff0c;决定写下来。首先&#xff0c;列举几种情况&#xff1a; 1.iPa包上传至App store后&#xff0c;一个小时内不显示构建版本…

如何使用Cloudreve将个人电脑打造为私有云盘并实现远程访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 云存储概念兴起后&#xff0c;现在市面上也已经有了很多公有云盘。但一段时间后…

关于easy-es的聚合问题-已解决

es实体类&#xff1a; public class ChemicalES {IndexId(type IdType.CUSTOMIZE)private Long id;HighLightIndexField(fieldType FieldType.TEXT, analyzer "ik_max_word")private String name;IndexField(fieldType FieldType.KEYWORD)private List<Stri…

2.安装docker

目录 1 安装依赖 2 安装docker 3 测试 目前docker分为三类 Docker-CE(社区版),Docker-EE(企业版)和Moby。Moby是docker社区用户自己写的&#xff0c;所以Moby我们一般用不上 每一类的每一个版本中都有Edge与Stable版&#xff0c;Stable维护4个月&#xff0c;Edge维护1个…