循坏队列+OJ题之设计循环队列

news2024/10/5 15:04:29

生命不是要等待风暴过去,而是要学会在风暴中跳舞。                ——卡莉尔·吉布朗
目录

🌺前言:

🍁一.循环队列是什么?

🍏二.循环队列有什么作用?

🍀三.OJ题之设计循环队列

1.创建循环队列的结构体

🏵️1.MyCircularQueue创建一个结构体指针

🍊3.myCircularQueueIsEmpty判断循环队列为空

🍀4.myCircularQueueIsFull判断循环队列为满

🍊5.myCircularQueueEnQueue往循环队列里面入元素 

🍂6.myCircularQueueDeQueue循环队列出元素 

🍁7.myCircularQueueFront返回对列头的元素

🍑8.myCircularQueueRear返回队列尾的元素

🍀9.myCircularQueueFree销毁循环队列

🍋四.完整代码


🌺前言:

之前我们学习了队列,队列是先进先出的一个结构,而且也写了几个OJ题了,想必对队列也是很熟悉了,之前也一直留了一个东西没有讲,那就是循环队列。今天就让我们一起来学习一下循环队列吧。

🍁一.循环队列是什么?

循环队列顾名思义,就是一个队列它是循环的,之前我们学习的单链表的队列,那么循环队列就可以是单向循环的单链表。
我们知道队列的结构可以链式的结构,也可以是顺序的结构。今天我们要讲的就是顺序结构的循环队列,顺序结构就是一个数组。

普通的顺序结构的队列:我们使用队头和队尾来记录元素的变化。

1.刚开始front和rear都指向数组的第一个位置,也就是下标为0的位置,初始化front和rear都为0,所以当front和rear相等的时候,那么即队列此时为空。
 

2. 此时我们可以入队列,也就是往队列里面入元素。入一个元素,rear就往后面走一步。

3.然后我们可以出队列,出一个元素,front就往后面加1。

如果我还要继续入队列就不行了,因为rear已经走到尾了,但是数组还没有满,这种情况我们就叫假溢出,然后循环队列就横空出世了,就是为了解决假溢出的问题。

🍏二.循环队列有什么作用?

循环队列就是为了解决队列假溢出的问题,可以更好的利用空间。
循环队列的逻辑结构:(注意逻辑结构是我们假象出来)

 

注意这里空的情况是front==rear,但是当我们入队列,把队列入满了之后,rear还是跑到了front的位置,这样就没法区分空和满的情况, 所以我们把队列的一个位置给空出来,不放元素使用,就是拿来区分满和空的情况,这种情况满了就rear+1==front。

知道了循环队列的用途,我们就来一个OJ题来练练手。

🍀三.OJ题之设计循环队列

题目描述:
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

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

示例:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1);  // 返回 true
circularQueue.enQueue(2);  // 返回 true
circularQueue.enQueue(3);  // 返回 true
circularQueue.enQueue(4);  // 返回 false,队列已满
circularQueue.Rear();  // 返回 3
circularQueue.isFull();  // 返回 true
circularQueue.deQueue();  // 返回 true
circularQueue.enQueue(4);  // 返回 true
circularQueue.Rear();  // 返回 4

做题链接:循环队列
接口函数:

typedef struct {

} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {

}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {

}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {

}

int myCircularQueueFront(MyCircularQueue* obj) {

}

int myCircularQueueRear(MyCircularQueue* obj) {

}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

}

bool myCircularQueueIsFull(MyCircularQueue* obj) {

}

void myCircularQueueFree(MyCircularQueue* obj) {

}

1.创建循环队列的结构体

typedef struct {
   int*a;//数组
   int front;//队列头
   int rear;//队列尾
   int k; //记录的队列的长度
} MyCircularQueue;

🏵️1.MyCircularQueue创建一个结构体指针

同样这里不是传参的方式,而是返回一个结构体的指针。

MyCircularQueue* myCircularQueueCreate(int k) {
   MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
   obj->a=(int*)malloc(sizeof(int)*(k+1));
   //记住这里数组长度是k,但是我们开k+1个空间,剩下的一个空间就拿来判断满的
   obj->front=obj->rear=0;
   obj->k=k;
   return obj;
}

🍊3.myCircularQueueIsEmpty判断循环队列为空

判断循环队列尾空,那可就太简单了。rear==front即为循环队列为空。

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

🍀4.myCircularQueueIsFull判断循环队列为满

对于判断队列满了,还得仔细斟酌一下,难道就是rear+1==front就为满了吗,其实不是这样的,因为我们开始画的是循环队列的逻辑结构,只是为了我们好理解。实际情况可不这样的,循环队列实际就一个普通的数组,循环就体现在一些特殊的手段上面,这个手段就是取余。

这个确实是rear+1==front就满了,但是如果是下面的情况呢 

就无法通过rear+1==front来判断满了,所以我们要使用取余来使得rear的下标和front重合。 

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1)==obj->front;//取余操作使得下标重合
}

🍊5.myCircularQueueEnQueue往循环队列里面入元素 

直接往队列为入元素即可,满了就无法入元素了。

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
     if(myCircularQueueIsFull(obj))//当队列为满时,那么久无法入队列了,直接返回false
        return false;
    obj->a[obj->rear]=value;
    obj->rear++;
    obj->rear%=(obj->k+1);//同样是取余,达到循环的目的
    return true;
}

🍂6.myCircularQueueDeQueue循环队列出元素 

bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
    if(myCircularQueueIsEmpty(obj))//队列为空,那么久无法出元素了,直接返回false
     return false;
     obj->front++;//队列头往后走,即是出元素
     obj->front%=(obj->k+1);
     return true;
}

🍁7.myCircularQueueFront返回对列头的元素

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))//为空,返回-1
       return -1;
    return obj->a[obj->front];
}

🍑8.myCircularQueueRear返回队列尾的元素

int myCircularQueueRear(MyCircularQueue* obj) {  
    if(myCircularQueueIsEmpty(obj))
       return -1;
       return obj->a[(obj->rear+obj->k)%(obj->k+1)];//这里是尾,同样要使用取余来循环
}

🍀9.myCircularQueueFree销毁循环队列

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

🍋四.完整代码

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));
   //记住这里数组长度是k,但是我们开k+1个空间,剩下的一个空间就拿来判断满的
   obj->front=obj->rear=0;
   obj->k=k;
   return obj;
}

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

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

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
     if(myCircularQueueIsFull(obj))//当队列为满时,那么久无法入队列了,直接返回false
        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))//为空,返回-1
       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);
}

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

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

相关文章

C++(3):字符串、向量和数组

命名空间的 using 声明 using namespace::name;1.每个名字都需要独立的 using 声明; 2.头文件不应包含 using 声明: 因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件里有某个using声明,那么每个使用了该头文件的文件就…

Apache Kafka - 重识Kafka生产者

文章目录 概述Kafka 生产者Kafka 生产者工作原理如何使用 Kafka 生产者 生产者配置项(核心)导图总结 概述 Kafka 生产者是 Apache Kafka 中的一个重要组件,它负责将数据发送到 Kafka 集群中。在实时数据处理和流式处理应用程序中&#xff0c…

如何自建个人音乐播放器Navidrome

文章目录 1. 前言2. Navidrome网站搭建2.1 Navidrome下载和安装2.1.1 安装并添加ffmpeg2.1.2下载并配置Navidrome2.1.3 添加Navidrome到系统服务 2.2. Navidrome网页测试 3. 本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4. 公网访问测试5. 结语 转…

【总结】Nupmy1

Nupmy numpy的核心是名为ndarray的数据类型,它代表多维数组,封装了操作数据的运算和方法 1. 创建数组对象 1.1 方法1:array 通过array将list转换成数据对象 # 通过array将list转换成数据对象 array1np.array([1,2,3,4,5]) array1 # array([1, 2, 3,…

Nginx + fastCGI 实现动态网页部署

简介 本文章主要介绍下,如何通过Nginx fastCGI来部署动态网页。 CGI介绍 在介绍fastCGI之前先介绍下CGI是什么。CGI : Common Gateway Interface,公共网关接口。在物理层面上是一段程序,运行在服务器上,提供同客户端HTML页面的…

测试理论----Bug的严重程度(Severity)和优先级(Priority)的分类

【原文链接】测试理论----Bug的严重程度(Severity)和优先级(Priority)的分类 一、Bug的严重程度(Severity) Bug的Severity(严重程度)指的是一个Bug对软件系统功能影响的程度&#…

Java常用工具之Collections

目录 一、排序操作二、查找操作三、同步控制三、不可变集合四、其他五、CollectionUtils:Spring 和 Apache 都有提供的集合工具类六 、小结 Collections 是 JDK 提供的一个工具类,位于 java.util 包下,提供了一系列的静态方法,方便…

2023河海大学846软件工程学硕考研高分上岸经验分享

大家好,我是陪你考研每一天的大巴学长。 大巴学长为大家邀请到了2023年846软件工程学硕刚刚上岸的学长,为大家分享一下他的考研经验,经验里详细介绍了各科的复习方法,很有参考意义。 希望对大家有所借鉴和帮助,在此向…

栈实现队列(继续细起来啊)

生命不是要等待风暴过去,而是要学会在风暴中跳舞。 ——卡莉尔吉布朗目录 🍁一.栈实现队列 🍀二.使用两个栈实现队列的功能 🌼1.在队列的结构体中创建两个栈 🚁2.创建一个队列的结构体指针 🌉3…

云计算中的大数据处理:尝试HDFS和MapReduce的应用

云计算中的大数据处理:尝试HDFS和MapReduce的应用 文章目录 云计算中的大数据处理:尝试HDFS和MapReduce的应用一、前言二、第一题1、命令方式2、java API方式 三、第二题1、创建CSV文件并将其上传到HDFS2、编写利用MapReduce框架的java代码3、打包java项…

【设计模式与范式:创建型】41 | 单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?

从今天开始,我们正式进入到设计模式的学习。我们知道,经典的设计模式有 23 种。其中,常用的并不是很多。据我的工作经验来看,常用的可能都不到一半。如果随便抓一个程序员,让他说一说最熟悉的 3 种设计模式&#xff0c…

Kelvin和Rossby波 Part-2(浅水方程)

在前面博主有篇关于Kelvin和Rossby波的简要介绍,见下: Kelvin和Rossby波 Part-1(简要介绍) 开尔文波(Kelvin Wave)是发生在大气或海洋中的,迎向地形边界(例如海岸线)平衡…

回顾2023年计算机专业学生卑微求职 / 申博血泪史

0.前言 2023年是悲惨的一年,各个行业都在卷中卷。同时对于个人来说,2023年也是最忙碌的一年,不仅面临毕业,而且面临工作/读博,随便挑出一件,都是一件耗时耗力的事。相信大家也从网络上看到了很多的帖子或者…

文心一言 VS 讯飞星火 VS chatgpt (19)-- go语言的slice和rust语言的Vec的扩容流程是什么?

go语言的slice和rust语言的Vec的扩容流程是什么? 文心一言: 在Go语言中,slice(切片)和Rust语言中的Vec都是用于存储一组固定长度的元素的数据结构。它们的扩容流程略有不同,下面是它们的基本概述&#xf…

HNU数据结构与算法分析-作业3-树结构

1. (简答题) 5.1 定义满二叉树的每一个结点或者是一个分支结点,并恰好有两个非空子结点;或者是叶结点。 证明在有n个分支结点的所有二叉树中,满二叉树的叶结点的数目(或者叶结点与全部结点数的比例)是最高的。 5.6 …

Linux下安装配置maven

1.安装以及配置maven 1.1.下载maven安装包 首先需要切换到自己需要安装的目录 把配置都放到了:/root路径下 1.2.解压下载好的maven包 tar -zxvf apache-maven-3.6.0-bin.tar.gzcp -r apache-maven-3.6.0 /usr/local/1.3.配置maven环境变量 1.3.1.在环境变量中…

微信小程序nodejs+vue校园二手商城交易(积分兑换)38gw6

随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,校园二手交易被用户普遍使用,为方便用户能够可以随时…

chatgpt赋能Python-python3_8怎么设置字体大小

Python3.8如何设置文本字体大小 Python是一种高级编程语言,它在全球开发者中间得到了广泛的应用。随着Python的不断发展,Python 3.8版本也应运而生。在这个新版本中,有许多新的功能,其中一个是设置文本字体大小。本文将展示如何在…

redis高级篇三(分片集群)

一)进行测试Sentinel池: 集群的定义:所谓的集群,就是通过增加服务器的数量,提供相同的服务,从而让服务器达到一个稳定、高效的状态 之前的哨兵模式是存在着一些问题的,因为如果主节点挂了,那么sentinel集群会选举新的s…