LeetCode622.设计循环队列

news2024/12/28 17:43:08

设计循环队列

  • 1.题目描述
  • 2.思路
  • 3.代码实现以及分析
    • 3.1 创建结构体
    • 3.2创建一个具体的循环队列
    • 3.3判断是否为空 和 判断是否为满
  • 4. 进队列 和 出队列
  • 5.取队首和队尾元素
  • 6.释放空间
  • 7.总结

1.题目描述


设计循环队列
在这里插入图片描述

2.思路

环形队列的抽象图

在这里插入图片描述

我们这里使用数组模拟实现循环队列,但是我们知道数组在实际当中并不是如上图这样的,我们要达成上图这样的效果可以多多利用 % 计算。

比如 任意一个数 % 5,得到的结果只能在 0 ~ 4 之间,所以我们可以利用这一性质,来完成我们的数组模拟实现循环队列。

3.代码实现以及分析

我们根据题目给的接口来一个个分析并实现

3.1 创建结构体

typedef struct {
    int* a;//a是数组
    int front;//队列头
    int rear;//队列尾
    int k;//k是数组有效空间,为什么说是有效空间?下面会解释
} MyCircularQueue;

3.2创建一个具体的循环队列

MyCircularQueue* myCircularQueueCreate(int k) {//k是队列的有效空间
//创建一个具体的结构
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//给我们的数组开辟 k + 1个空间,k + 1就是实际的空间,这个空间不存数值
    obj -> a = (int*)malloc(sizeof(int) * (k + 1));//多开一个空间,实现”假溢出“
    obj -> front = 0;//队首和队尾的下标都初始化为0
    obj -> rear = 0;
    obj -> k = k;//传入接口函数的大小k
    return obj;
}

3.3判断是否为空 和 判断是否为满

我们可以让front == rear时,循环队列为空。那么怎么判断是否为满呢?
我们可以多开一个空间这个空间不存放任何值,当rear + 1 == front时,则循环队列为满,这种现象叫做“假溢出”
这就是我们为什么要多开一个空间,目的就是利用假溢出来判断循环队列是否为满。

判空:
在这里插入图片描述

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

判满:(需要注意一些情况)

正常情况:这种情况只需判断rear + 1 == front 是否成立就可以了。

在这里插入图片描述

特殊情况:下面这种情况当rear + 1时,就会造成数组的越界。这时候就需要用到我们上面提到的 % 操作。
(rear + 1) % (k + 1) == front,可以让等号左边的值在0 ~ k 中循环,避免越界的情况。
如下图 front的下标为0,rear的下标为5,k为5 (5 + 1) % (5 + 1) == 0,可以看到可以成功判满。
利用 % 操作,不管时那种情况都能准确判断是否为满。

在这里插入图片描述

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

4. 进队列 和 出队列

进队列前,注意判断队列是否为满。
和普通队列一样,进队列让队尾++就可以了,注意当rear在末尾时越界情况。

当rear++后,可能会越界,此时rear应该在0下标处
同样可以进行 % 操作 rear %= k + 1
在这里插入图片描述

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj)) return false; //如果队列已满则入队列失败,返回false

    obj -> a[obj -> rear++] = value; //进队列以后,rear++
    obj -> rear %= obj -> k + 1;//防止越界情况
    return true;//进队列成功返回true
}

出队列前,也应该判断队列是否为空,为空则返回false,表示出队列失败
和普通队列一样,出队列让队首++就可以了,注意越界情况

此时front应该在0下标处
%操作 front %= k + 1 即可
在这里插入图片描述

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj)) return -1;

    return obj -> a[obj -> front];
}

5.取队首和队尾元素

取队首元素很简单,直接取下标对应位置的值就可以了

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj)) return -1;//判空

    return obj -> a[obj -> front];
}

取队尾元素比较麻烦一点,因为rear位置是不存放值的所以队尾元素实际是 rear 的前一个位置

下图的队尾是rear 的前一个位置的元素,也就是44,一般情况下rear-1就可以得到队尾元素。
这里是特殊情况,同样利用%操作
(rear - 1 + k + 1) % (k + 1),也就是
(rear + k) % (k + 1),就可得到适应各种情况的获取队尾下标方法。
在这里插入图片描述

int myCircularQueueRear(MyCircularQueue* obj) { //尾不是rear,而是rear的前一位
    if(myCircularQueueIsEmpty(obj)) return -1;
    
    return obj -> a[(obj -> rear + obj -> k ) % (obj -> k + 1)];
}

6.释放空间

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj -> a); //先释放我们创建的数组
    free(obj);//再释放我们创建的结构
}

7.总结

设计循环队列,要设计好判空和判满情况。
其中,判满要利用“假溢出”这一特性。
利用数组设计循环队列的时候,利用%操作来达成我们的“循环”

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

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

相关文章

TransactionTemplate自动注入,只看这一篇文章就够了

标准的springboot接入mybatis步骤 1.引入了对应的依赖包 2.应用的properties下增加相应配置 3.根据配置进行自动装配 一般我们会配置这些信息,主要包括三类 1.数据库的连接信息 2.指定的数据源类型 3.mybatis的配置信息 配完以后,当你启动SpringBoot的主…

你是真的“C”——详解C语言数组模块知识

详解C语言数组模块知识😎前言🙌一维数组的创建和初始化🙌1.1 数组的创建💞1.2 数组的初始化💞1.3 一维数组的使用💞1.4 一维数组在内存中的存储💞二维数组的创建和初始化🙌1.1 二维数…

【Python百日进阶-数据分析】Day225 - plotly的Ohlc图go.Ohlc()

文章目录一、语法二、参数三、返回值四、实例4.1 简单的OHLC图4.2 隐藏滑块的OHLC图4.3 添加自定义文本和注释4.4 自定义OHLC颜色4.5 带日期时间对象的简单的OHLC图4.6 自定义悬浮文本4.7 Dash中的应用一、语法 ohlc(Open-High-Low-Close 的缩写)是一种…

【C++逆向】虚表(Virtual table)逆向 | 安卓so虚函数逆向

什么是多态 定义一个虚基类ISpeaker class ISpeaker{ protected:size_t b; public:ISpeaker( size_t _v ): b(_v) {}virtual void speak() 0; };有两个子类,都实现了虚函数speak(): class Dog : public ISpeaker { public:Dog(): ISpeaker(0){}//vir…

1581_AURIX_TC275_SMU故障处理梳理

全部学习汇总: GreyZhang/g_TC275: happy hacking for TC275! (github.com) 前面为了缓解自己的学习压力,一次学习笔记大概也就是看10页文档整理一下。这一次其实是看了几十页,但是里面过掉了一些信息,而且这部分内容不是很好拆分…

hive在IDEA中debug

一、hive在IDEA中debug 安装hadoop环境(1和2替换顺序也可以) 注:hadoop环境不需要从源码编译 https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html 按照官网教程编译源码 https://cwiki.apach…

软件工程专业课实验报告

一、结构化分析方法1.1需求描述教务管理子系统的需求描述:教务管理是一项需求周密计划、严谨安排的工作,要依据教师、学生信息进行合理安排。开学阶段,需要教师提交开课申请进行开课,学生根据老师的开课信息,选择课程&…

uview 使用遇到的问题。

uviewuniappvue,uView是uni-app生态专用的UI框架。 1. 注意uview版本,uview 2.0与uview1.0 官方提示:uView2.0是继1.0以来的一次重大更新,2.0已全面兼容nvue。 因此在接手项目的时候首先得看清楚,之前开发的是uview…

【自学Python】Python获取字符串长度

Python获取字符串长度 Python获取字符串长度教程 在 Python 中要想获取 字符串 长度可以使用 len() 函数。 Python len()函数详解 定义 我们将要获取的字符串的长度,传进 len() 函数,即可实现获取字符串的长度。 语法 len(string)参数 参数描述s…

【7】K8s_Ingress | Service的统一网关入口

目录 1、Ingress简介 2、安装ingress 【1】制作ingress.yaml文件并执行 【2】测试,创建一个test.yaml文件并执行 【3】设置域名访问,用yaml文件 【4】路径重写 【5】流量限制 1、Ingress简介 Ingress: Service的统一网关入口是k8s中的一个api对象&…

时序数据库TDengine基本概念和建模思路

目录 一 、 时序数据库基本概念 采集量 标签 数据采集点 表 超级表 子表 库 二、 TDengine数据库建模策略 建表模式建表情形 行列数据库存储的区别: 接触的传统业务的数据模式都是行存储,我们会把不同类型的对象创建不同的表进行存储他们各自的属…

机器学习公式推导与代码实现-无监督学习模型

聚类分析与k均值聚类算法 督学习算法。在给定样本的情况下,聚类分析通过度量特征相似度或者距离,将样本自动划分为若干类别。 距离度量和相似度度量方式 距离度量和相似度度量是聚类分析的核心概念,大多数聚类算法建立在距离度量之上。常用的距离度量方式包括闵氏距离和马…

linux系统中使用QT来实现数据库的调用方法

大家好,今天主要和大家分享一下,如何使用QT中数据库的使用方法。 目录 第一:数据库基本简介 第二:数据库表格基本操作 第三:数据库最终效果 第一:数据库基本简介 数据库是按照数据结构来组织,…

视频目标检测与轨迹跟踪代码案例

前言通过阅读相关文献及测试,找到了一种基于多模板匹配的改进方法,可以对遥感视频卫星中的移动目标进行探测,并绘制其轨迹。根据实验结果发现,可以比较有效的对运动目标进行跟踪。一、原理核心思想比较简单。即通过不同旋转角度的…

AQS之ReentrantLock详解

非公平锁加锁过程一般我们在使用ReentrantLock的时候,代码如下:Test public void test(){ReentrantLock lock new ReentrantLock();lock.lock();try{//编写业务逻辑}catch (Exception e){lock.unlock();} }当我们在用ReentrantLock独占锁的时候&#xf…

current并发包

并发包 current并发包、在JDK1.5之前Java并没有提供线程安全的一些工具类去操作多线程,需要开发人员自行编写实现线程安全,但仍然无法完全避免低性能、死锁、资源管理等问题。在JDK1.5时新增了java.util.current并发包,其中提供了许多供我们…

【自学Python】Python截取字符串

Python截取字符串 Python截取字符串教程 在 Python 中,我们需要截取 字符串,不需要使用特定的 函数,只需要使用下标索引加上切片的形式,就可以实现字符串的截取。 Python字符 Python 中没有单个字符的概念,单个字符…

uni-app 微信小程序通过Vue3 Hooks 实现动态填充页面剩余高度

应用场景 在uni-app开发微信小程序等项目时,经常会遇到这样的页面布局需求:上半部分高度固定,下半部分自动占满剩余高度,如下图所示应用场景:上半部分为固定高度或内容填充高度的内容区域下半部分为scroll-view滑动区…

河北稳控科技振弦采集模块配置工具VMTool的常见功能

河北稳控科技振弦采集模块配置工具VMTool的常见功能 一、实时数据读取 当 VMTool 与模块为连接状态时( 4.3.1 模块的连接与断开), 勾选实时数据区的【 自动读取】 复选框, VMTool 开始自动向模块发送实时数据读取指令&#xff0c…

如何用 Java 来构建一个简单的速率限制器?

速率限制 现实世界中的用户是残暴的,并且没耐心,充满着各种不确定性。在高并发系统中,可能会出现服务器被虚假请求轰炸的情况,因此您可能希望控制这种情况。 一些实际使用情形可能如下所示: API配额管理-作为提供者…