C语言/数据结构——每日一题(设计循环队列)

一.前言

上一次我们分享了关于队列的基本实现——https://blog.csdn.net/yiqingaa/article/details/139033067?spm=1001.2014.3001.5502

现在我们将使用队列知识来解决问题——设计循环队列:https://leetcode.cn/problems/design-circular-queue/submissions/533299335

二.正文

1.1题目描述

1.2题目分析

本题给了我们七个操作需求,需要我们将这些函数功能实现出来。

对于这道题,假如我们是使用数组来实现队列,在这里我们可以事先模拟走一下:

那么我们如何解决这个问题呢。在这里我们我们可以通过多创建一个空间的方式解决这个问题。

(1)定义栈的结构

typedef struct {
    int* a;//a是int*类型的数组
    int k;//k代表了我们的数组长度
    int head;//head会指向我们的头元素(head在这里不是指针,可以当成另类的下标)
    int tail;//tail在我们数据的后一个位置(tail在这里不是指针,可以当成另类的下标)
} MyCircularQueue;

假如k是4,数组有1,2,3,4这些数据。那么就有:

 (2)创建我们的队列

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    if(obj->a==NULL)
    {
        perror("malloc fail!");
    }
    obj->k=k;
    obj->head=obj->tail=0;
    return obj;
}

我们首先为我们的队列结构体申请了sizeof(MyCircularQueue)字节大小的空间。

然后又为了我们数组申请了sizeof(int)*(k+1)字节大小的空间。

用我们的结构体成员k接受形参k的值。

并让head,tail都初始化为0。

(3)判断队列是否为空

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    if(obj->head==obj->tail)
    return true;
    return false;
}

这里我们先实现了判断队列是否为空的函数功能,因为这个函数功能在后面实现数据插入和删除中都需要用到,因此,在这里我们就先实现了。

 (4)判断队列是否数据已满

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    if((obj->tail+1)%(obj->k+1)==obj->head)
    return true;
    return false;
}

 (5)队列数据的插入

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

这里我们先进行了判断,如果队列数据已经满了,就插不了数据了,直接返回false即可。

在这里,我们需要额外注意这行代码:obj->tail=(obj->tail)%(obj->k+1);

相信同学们看到这里已经发现了,我们上述代码中很多都用到了取余%的应用,这是为了让head和tail能正常的循环。

(6) 队列数据的删除

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

这里我们需要知道,如果队列没有数据的时候,我们不能进行数据删除,因为本来队列都没数据了,再删除就会出现内存泄露的问题。

(7) 取出队头的数据

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

 (8)取出队尾的数据

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

 (9)销毁我们创建的对列

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

 1.3代码实现




typedef struct {
    int* a;
    int k;
    int head;
    int tail;
} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    if(obj->a==NULL)
    {
        perror("malloc fail!");
    }
    obj->k=k;
    obj->head=obj->tail=0;
    return obj;
}

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

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

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

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

int myCircularQueueRear(MyCircularQueue* obj) {
      if(myCircularQueueIsEmpty(obj)==true)
    return -1;
    return obj->a[(obj->tail-1+obj->k+1)%(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);
*/

以上代码就是我们在力扣网上运行的代码。

三.结言

本题的分享就到这了,有兴趣的小伙伴,能不能给个三连,真的求求了。

帅哥美女们,咱们下期再见。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

振弦式渗压计的维护和校准:确保数据准确性的关键步骤

振弦式渗压计是一种用于测量土壤和岩石中孔隙水压力的高精度仪器。它广泛应用于土木工程、水利工程、地质灾害监测等领域,准确性直接影响到工程安全和监测数据的可靠性。因此,对振弦式渗压计进行适当的维护和校准是至关重要的。本文将探讨振弦式渗压计的…

2024-5-6-从0到1手写配置中心Config之实现配置中心客户端

配置加载原理 在Spring中PropertySource类实现了所有属性的实例化。 启动赋值: 定义自定义属性配置源,从config-server获取全局属性;Spring启动时,插入自定义属性配置源;绑定属性会优先使用,给自定义属性…

tomcat jdbc连接池的默认配置配置方案

MySQL 5.0 以后针对超长时间数据库连接做了一个处理,即一个数据库连接在无任何操作情况下过了 8 个小时后(MySQL 服务器默认的超时时间是 8 小时),MySQL 会自动把这个连接关闭。在数据库连接池中的 connections 如果空闲超过 8 小时,MySQL 将…

python期末作业:批量爬取站长之家的网站排行榜数据并保存,数据分析可视化

爬虫作业,含python爬取数据和保存文件,数据分析使用pyecharts做数据可视化 整体上分析网站的排名,直观看各个网站的热度。 数据分析之后大致的效果: 整个项目分为两个大的部分,第一部分就是抓取网站排名数据,然后保存为Excel、csv等格式,其次就是从文件中…

Advanced Installer 使用教程-自定义操作(下)

1、点击左侧“必要条件”,选择“运行环境” 2、这个运行环境用于设置安装前、中、后,各个阶段的自定义操作 3、安装过程中的自定义操作 1)右击基本特征,选择新建程序包先决条件,在弹出的对话框中选择自己的EXE任务程…

Live800:客户为王,企业竞争的新趋势与核心要素!

在企业经营管理中,客户始终是最重要的资源和战略。从企业经营的角度来说,企业管理的核心是客户管理,客户管理的核心是价值创造和价值分配,这是企业经营的基础。这里主要讨论了企业竞争的新趋势与核心要素,认为客户为王…

营收净利双降、股东减持,大降价也救不了良品铺子

号称“高端零食第一股”的良品铺子(603719.SH),正遭遇部分股东的“用脚投票”。 5月17日晚间,良品铺子连发两份减持公告,其控股股东宁波汉意创业投资合伙企业、持股5%以上股东达永有限公司,两者均计划减持。 其中,宁…

【minio】minio文件访问不到问题记录

问题描述: 项目上上传了logo,但是无法回写logo,但是文件minio路径已经返回,并且到minio服务器上也能下载文件; 解决方案: 1.排查Nginx的代理的minio是否正确 2.登录minio服务查一下文件路径policy是否设置访…

国内大模型价格战全面爆发:新旧势力逐鹿江湖【附主流模型价格对比】

近年来,随着人工智能技术的不断发展,大模型逐渐成为行业的焦点。然而,伴随而来的却是一场价格战。DeepSeek率先推出超低价服务,随后字节跳动、阿里巴巴、百度、科大讯飞、腾讯等巨头纷纷跟进,使得这一领域的竞争愈演愈…

研发机构大数据迁移如何保障敏感数据不泄露

随着云计算和大数据技术的飞速进步,越来越多的企业正试图通过数据迁移来提升IT基础设施的效率,减少成本,并增强业务的灵活性。但是,这一过程并非没有它的挑战,尤其是在数据安全方面。数据在转移过程中可能会遭遇黑客攻…

Python使用thread模块实现多线程

介绍: 线程(Threads)是操作系统提供的一种轻量级的执行单元,可以在一个进程内并发执行多个任务。每个线程都有自己的执行上下文,包括栈、寄存器和程序计数器。 在Python中,可以使用threading模块创建和管理…

设计模式5——抽象工厂模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 抽象工厂模式(Abst…

Docker+nginx部署SpringBoot+vue前后端分离项目(保姆及入门指南)

前后分离项目部署 项目回顾工具上线准备1、win1.1、前端1.2、后端 2、linux环境2.1、安装docker2.2、安装docker compose2.3、编写Dockerfile文件2.4、编写docker-compose.yml文件2.5、修改application-pro.yml2.6、准备好nginx的挂载目录和配置2.7、部署后端服务 项目回顾 书…

Pod容器资源限制和探针

目录 一、资源限制 1.Pod和容器的资源请求和限制 2.CPU 资源单位 案例一 案例二 二、健康检查,又称为探针(Probe) 1.探针的三种规则 2.Probe支持三种检查方法 3.探测获得的三种结果 案例一:exec 案例二:htt…

C语言/数据结构——每日一题(有效的括号)

一.前言 如果想要使用C语言来解决这道题——有效的括号:https://leetcode.cn/problems/valid-parentheses/description/我们必须要借用上一篇我们所讲的内容——栈的实现:https://blog.csdn.net/yiqingaa/article/details/138923750?spm1001.2014.3001.…

LLM实战:当网页爬虫集成gpt3.5

1. 背景 最近本qiang~关注了一个开源项目Scrapegraph-ai,是关于网页爬虫结合LLM的项目,所以想一探究竟,毕竟当下及未来,LLM终将替代以往的方方面面。 这篇文章主要介绍下该项目,并基于此项目实现一个demo页面&#x…

【linux】深入了解线程池:基本概念与代码实例(C++)

文章目录 1. 前言1.1 概念1.2 应用场景1.3 线程池的种类1.4 线程池的通常组成 2. 代码示例2.1 log.hpp2.2 lockGuard.hpp① pthread_mutex_t 2.3 Task.hpp2.4 thread.hpp2.5 threadPool.hpp① 基本框架② 成员变量③ 构造函数④ 其余功能函数: main.cc结果演示 完整…

车载网络测试实操源码_使用CAPL脚本模拟发送符合协议要求(Counter和CRC)的CAN报文

系列文章目录 车载网络测试实操源码_使用CAPL脚本解析hex、S19、vbf文件 车载网络测试实操源码_使用CAPL脚本对CAN报文的Counter和CRC进行实时监控 车载网络测试实操源码_使用CAPL脚本模拟发送符合协议要求(Counter和CRC)的CAN报文 车载网络测试实操源码_使用CAPL脚本实现安全…

Go语言实现人脸检测(Go的OpenCV绑定库)

文章目录 OpenCVGithub官网安装环境变量 Go的OpenCV绑定库Github文档安装搜索视频设备ID显示视频检测人脸 OpenCV Github https://github.com/opencv/opencv/ 官网 https://opencv.org/ 安装 brew install opencv brew upgrade opencv安装目录 cd /usr/local/opt/opencv…

做OZON怎么选择物流,OZON物流Xingyuan

随着跨境电商的蓬勃发展,OZON作为俄罗斯领先的电商平台,吸引了大量中国卖家入驻。然而,物流作为跨境电商的关键环节,其选择对于卖家来说至关重要。本文将围绕“做OZON怎么选择物流”这一问题,深度解析OZON物流Xingyuan…