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

news2024/10/7 16:16:24

一.前言

上一次我们分享了关于队列的基本实现——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);
*/

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

三.结言

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度神经网络——什么是自动编码器?

自动编码器 自动编码器(Autoencoders)是无监督学习领域中一种重要的神经网络架构,它们主要用于数据压缩和特征学习。 自动编码器的定义: 自动编码器是一种无监督机器学习算法,它通过反向传播进行训练,目标…

【从C++到Java一周速成】章节10:封装、继承、方法的重写、多态

章节10:封装、继承、方法的重写、多态 【1】封装1.高内聚,低耦合2.代码层面的体现 【2】继承【3】方法的重写【4】多态 【1】封装 1.高内聚,低耦合 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;…

如何使用 CapSolver 扩展找到 Google reCAPTCHA 站点密钥?

网站安全性在当今至关重要,Google reCAPTCHA 作为防止垃圾邮件和滥用行为的前线防御系统起着关键作用。reCAPTCHA 站点密钥是确保网站交互由人类驱动的唯一标识符。了解如何找到这个密钥对于网站管理员和开发人员来说至关重要。 什么是 reCAPTCHA 站点密钥 reCAPT…

智能家居6 -- 配置 ini文件优化设备添加

不知道什么是ini的朋友可以先看这篇:一文带你入门ini格式-CSDN博客 准备 如下图: 在src 下面添加 ini.c 在inc 下面添加 ini.h 在 receive_interface.c 里面包含头文件,把之前添加的设备类注释掉 这时候就可以把相关设备的(.c .h)文件给删掉了 如下图: 修改/添…

CDH6.3.2集成Flink1.17

直接运行脚本即可,一键输出相关依赖包 运行步骤已给到文档 下载地址

更新评估班级、确定评价学生

场景: 义务阶段为何要进行分层分班,这一点大家都心知肚明。你说的答案是不是也和我的一样:为了实行分层教学。"人往高处走,水往低处流",每次确定分班后,总会有一些学生向上调整,当然也…

python2.x版本安装、安装pip

文章目录 一、安装python二、安装pip2.1、pip简介2.2、pip安装2.3、no such option: -e2.4、pip卸载2.5、pip扩展 本文讲解在windows系统装安装python2.7.13版本 一、安装python 1.下载安装包,官网链接地址:https://www.python.org/downloads/ 直接在…

Pytorch深度学习实践笔记4

🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:pytorch深度学习 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致重复! 视频来自【b站刘二大人】 1 反向传播 Back propaga…

机器视觉HALCON:2.HALCON的预备环境和数据结构

目录 下载基础语法HALCON的数据结构图像和数据类型区域的存储区域的存储连通区域 亚像素轮廓(XLD)亚像素轮廓介绍亚像素轮廓数据结构 数组数组的赋值与创建数组的存储与读取 字典字典介绍字典的创建和操作 句柄 下载 HALCON的官方网站 下载时需要注册登…

react antd中transfer穿梭框组件中清除搜索框内容

如图:需要清除search搜索框内容 antd的transfer穿梭框组件未提供入口修改input框的值。 2种方法修改。 1、直接操作dom元素设置值(不推荐) useEffect(() > {const searchInput document.querySelector(.ant-transfer-list-search input)…

Redis常用命令——String篇

前面我们讲解了一些 Redis 的全局命令(Redis常用基本全局命令)。所谓全局命令,就是可以匹配任意一个数据结构进行使用。但是不同的数据结构,也有自己的操作命令。本篇文章主要讲解的是 String 的操作命令,希望会对你有…

2024电工杯B题:大学生平衡膳食食谱的优化设计及评价

大学时代是学知识长身体的重要阶段,同时也是良好饮食习惯形成的重要时期。这一特 定年龄段的年轻人,不仅身体发育需要有充足的能量和各种营养素,而且繁重的脑力劳动和 较大量的体育锻炼也需要消耗大量的能源物质。大学生中饮食结构不合理以及…

在抖音怎么开店?抖音小店开店步骤详解!建议收藏!

大家好,我是电商小V 想在抖音上面开一家属于自己的抖音店铺去卖点商品赚取个商品的差价,那么开通抖音小店的步骤是什么呢?主要分为几步呢?关于这个问题咱们就来详细的说一下: 开店之前的准备工作,首先需要准…

核心四:线程的一生

4、核心四:线程的一生💟 4.1 New 已创建但还未启动的新线程。 我们new Thread之后,线程已经实现了一些准备工作。但没有运行run方法,因为没有使用start来开启线程。此时,线程处于New状态。 4.2 Runnable&#xff08…

Python模块、包和异常处理

大家好,在当今软件开发领域,Python作为一种简洁、易读且功能强大的编程语言,被广泛应用于各种领域。作为一名测试开发工程师,熟练掌握Python的模块、包和异常处理是提高代码可维护性和错误处理能力的关键。本文将和大家一起探讨Py…

Linux —— 信号量

Linux —— 信号量 什么是信号量P操作(Wait操作)V操作(Signal操作)信号量的类型 一些接口POSIX 信号量接口:其他相关命令: 基于循环队列的生产者和消费者模型同步关系 多生产多消费 我们今天接着来学习信号…

5.22R语言初步学习-1

今天上课讲R语言,要干什么没讲,分析什么,目的是什么没讲。助教基本上就是让我们打开窗口,按要求抄代码指令,代码原理也没讲......再加上最近正好在学概率论与数理统计,肯定是有用的,所以还是学习…

(全面)Nginx格式化插件,Nginx生产工具,Nginx常用命令

目录 🎫 前言 🎉 开篇福利 🎁 开篇福利 x2 Double happiness # 介绍 # 地址 # 下载 💻 命令及解析 # 整个文件系统中搜索名为nginx.conf的文件 # 编辑nginx.conf文件 # 重新加载配置文件 # 快速查找nginx.conf文件并使…

HTTP协议请求报头(header)

目录 目录 User-Agent与Referer User-Agent Referer Cookie HTTP报头(header)的结构是“键值对”结构,每个键值对占一行,键和值之间使用分号分隔。 报头的种类有很多,本次介绍几个重要的。 Host:表示请…