速学数据结构 | 循环队列怎么写才最高效?只需要掌握这些技巧


在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏:《Linux深造日志》《C++干货基地》

⛺️生活的理想,就是为了理想的生活!

文章目录

  • 📋 前言
  • 一、什么是循环队列?
  • 二、如何实现循环队列?
    • 2.1 循环队列的结构
    • 2.2 循环队列的初始化
    • 2.3 如何检查队列是非为空
    • 2.4 如何检查队列是否满了
    • 2.5 循环队列如何插入数据
    • 2.6 循环队列如何删除数据
    • 2.7 获取循环队列头元素
    • 2.8 获取循环队列尾元素
    • 2.9 如何销毁循环队列
  • 三、循环队列练习
      • 循环队列结构代码:
      • 循环队列练习题
  • 📝全篇总结

📋 前言

  🌈hello! 各位宝子们大家好啊,今天给大家带来循环队列的详细解析,队列我们会写了那么循环队列呢?今天这个还是有点难度的
  ⛳️学完之后保证你对队列又会有一个更清晰的认识。让你彻底拿捏队列循环队列一搞完我们的队列学习就告一段落了。
  📚本期文章收录在《数据结构&算法》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

一、什么是循环队列?

队列我们都自动是数据结构中类似排队一样的结构,主要满足:先进先出的特点。而循环队列的话顾名思义就是把头和尾链接起来循环这样就是循环队列了。

  • 下面我们就来看一下他大概得物理图吧!

在这里插入图片描述

上面是为了方便大家理解而做的图,而实际的循环队列是这样的

在这里插入图片描述

二、如何实现循环队列?

这里我们先看一下力扣上面的题目要求我们,要实现循环队列要实现的功能然后再进行逐个实现就好了。

  • 循环队列链接:622. 设计循环队列
    在这里插入图片描述

2.1 循环队列的结构

首先我们需要考虑的就是循环队列的结构,很多人可就会想到使用链表去实现循环队列但是这里有俩个问题:

  • 循环队列如何判空和满?
  • 如果让 rear 指向有数据的那么插入第一个数据的时候是否为空?
  • 如果让rear 指向数据后面的空间那么 尾元素该如何去找?
  • 如果 rear 满了如何判定是否为空

在这里插入图片描述

所以为了解决这种情况我们选择试用数组的方式实现,多开一个元素来实现循环链表就完美解决问题了:

  • 使用 下标访问 解决找不到前一个元素的问题
  • 而假溢出问题:我们多开了一个空间可以解决空和满的问题

2.2 循环队列的初始化

好了上面我们已经知道了循环队列用哪种方式更优,那么接下来就是设计循环队列的结构了:

  • 首先我们需要一个 int* 的指针来开辟数组
  • 然后需要一个头 front 当下标
  • 需要一个尾 rear 来当尾数据的下一个下标
  • 需要一个 k 来接收开辟队列的长度

📚 代码演示:

ypedef 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));
    obj->front = obj->rear = 0;
    obj->k = k;

    return obj;
}

2.3 如何检查队列是非为空

这个就更加简单我们我们前面说了:

  • 只要 front == rear 就为空,因为没有数据俩个都是同一个下标。

📚 代码演示:

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

2.4 如何检查队列是否满了

如何检查队列是否满了,就需要判断一下 rear 的下一个是否为 front 了:

  • 这里需要注意的是 rear 的过界问题,如何让下标回归正常
  • 其实只需要 模除 一下就好了

📚 代码演示:

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

2.5 循环队列如何插入数据

循环队列插入数据的话,首先要判断是否为满就然后插入就行了:

  • 然后 ++obj->rear 了之后要考虑一下 rear 在最后一个位置的情况
  • 模除一下就好了

📚 代码演示:

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

    return true;
}

2.6 循环队列如何删除数据

删除数据也是一样,循环队列如果空了就返回 false 没空 front++ 就好了:

  • 同样要注意控制好front的边界值

📚 代码演示:

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

    
}

2.7 获取循环队列头元素

获取头元素就很简单啦,只需要使用 front 来当下标访问就好了

📚 代码演示:

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

2.8 获取循环队列尾元素

这里就需要考虑很多问题,rear是尾元素的下标的一个一个下标:

  • 我们需要要考虑如果 rear 指向最后一个空间怎么办?
  • rear 指向中间怎么办? 如何回到上一个
  • rear 下标为零的时候 如何回到他的上一个下标

📚 代码演示:

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

2.9 如何销毁循环队列

销毁就很简单了,先 free 掉我们动态开辟的空间,在free掉循环队列的空间就好了:

📚 代码演示:

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

三、循环队列练习

循环队列结构代码:

📚 代码演示:

typedef struct {
    int* a;
    int front;
    int rear;
    int k;

} MyCircularQueue;

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

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->k+1) == obj->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 myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        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;
    else
        return obj->a[obj->front];
}

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



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

循环队列练习题

这里我们可以去力扣一下检验和练习一下:

  • 这章内容还是比较有难度的,可以多琢磨琢磨
  • 力扣题目链接: 循环队列

在这里插入图片描述

📝全篇总结

☁️ 把本章的内容全部掌握,铁汁们对于队列的理解就更上一层楼了!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

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

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

相关文章

SpringBoot集成MyBatis-Plus

SpringBoot集成MyBatis-Plus 文章目录 SpringBoot集成MyBatis-Plusapplication.ymlpom.xmlpojomapperserviceserviceimplconfigutilsweb 懒得打一遍,直接copy: SpringBoot集成MyBatis-Plus application.yml # 端口 server:port: 8080 # 数据源 spring:…

期中成绩怎么发布?

作为一名老师,期中考试结束后,你可能正在为如何发布成绩而烦恼。传统的纸质方式不仅耗时而且容易出错,那么有没有一种方式可以让学生自助查询成绩呢?答案是肯定的。下面就为你介绍几种实用的方法,让成绩发布变得轻松又…

默认路由配置

默认路由: 在末节路由器上使用。(末节路由器是前往其他网络只有一条路可以走的路由器) 默认路由被称为最后的关卡,也就是静态路由不可用并且动态路由也不可用,最后就会选择默认路由。有时在末节路由器上写静态路由时…

性能优于BERT的FLAIR:一篇文章入门Flair模型

文章目录 What is FLAIR?FLAIR ModelContextual String Embedding for Sequence Labelingexample FLAIR Application AreaSentiment AnalysisNamed Entity RecognitionText Classification FLAIR一、什么是FLAIR?二、FLAIR Library的优势是什么&#xff…

日本it培训学费 想去日本做IT,需要具备哪些技术?

日本的IT行业历史比较悠久,业务以上层前端业务为主,如设计和构建软件。日本IT公司组织庞大,行业内部有着严格的分工和部署,工作会被细分化,分配给个人的工作量不会太大,难度也不会很高,所以日本…

【JAVA学习笔记】59 - JUnit框架使用、本章作业

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter15/src/com/yinhai/homework JUnit测试框架 1.基本介绍 1. JUnit是一个Java语言的单元测试框架 2.多数Java的开发环境都已经集成了JUnit作为单元测试的工具 2.如何使用 创建方法后&#x…

关于msvcp120.dll丢失的解决方法详解,快速解决dll丢失问题

在计算机使用过程中,经常会遇到“msvcp120.dll丢失”的错误提示。这个错误提示通常出现在运行某些程序或游戏时,造成相关应用程序可能无法正常启动或运行。那么,究竟是什么原因导致了msvcp120.dll文件的丢失呢?本文将详细解析msvc…

react使用react-sortable-hoc实现拖拽

react-sortable-hoc拖拽 安装 npm install react-sortable-hoc --save 代码如下(示例): import React, { useImperativeHandle, forwardRef, memo, useState } from react;import { DrawerForm } from ant-design/pro-form;import { messag…

竖拍的视频怎么做二维码?竖版视频二维码制作技巧

为了方便视频的展示和传播,现在将视频生成二维码后来使用的方式越来越常见,很多做二维码工具都可以制作视频二维码,但是无法设置下载权限或者播放竖版视频。那么如果做有下载功能的视频码该如何制作,可能很多小伙伴都不知道怎么做…

Idea 对容器中的 Java 程序断点远程调试

第一种:简单粗暴型 直接在java程序中添加log.info(),根据需要打印信息然后打包覆盖,根据日志查看相关信息 第二种:远程调试 在IDEA右上角点击编辑配置设置相关参数在Dockerfile中加入 "-jar", "-agentlib:jdwp…

可视化协作软件有哪些?这10款神器助力团队合作!

可视化协作已经成为一个时下热门词汇,问题是对其并没有一个清晰的定义。有人认为它代表了一个云端环境,具有能够使办公室、混合办公和远程员工一起工作的功能。其他人则认为可视化协作不过是数字化白板而已。 随着这个术语变得更加流行,许多…

时间序列聚类的直观方法

一、介绍 我们将使用轮廓分数和一些距离度量来执行时间序列聚类实验,同时利用直观的可视化,让我们看看下面的时间序列: 这些可以被视为具有正弦、余弦、方波和锯齿波的四种不同的周期性时间序列 如果我们添加随机噪声和距原点的距离来沿 y 轴…

Flutter 组件集录 | InheritedNotifier 内置状态管理组件

theme: cyanosis 1. 前言 在上一篇 《Flutter 知识集锦 | 监听与通知 ChangeNotifier》 中,我们介绍了 ChangeNotifier 对象通知监听者的能力。并通过一个简单的模拟下载进度案例,介绍了它的使用方式: | 案例演示 | 监听-通知关系 | | --- | …

多用户商城系统对比 多用户商城系统哪个好

大环境越来越好,企业纷纷将消费者引入自己建设的独立商城,如零食行业的良品铺子、三只松鼠,从而打造属于自己的IP形象。此时,挑选一款优秀的商城源码是企业的不二之选。这里将国内三大优秀的多用户商城系统进行对比,以…

Elasticsearch 8.X 如何生成 TB 级的测试数据 ?

1、实战问题 我只想插入大量的测试数据,不是想测试性能,有没有自动办法生成TB级别的测试数据?有工具?还是说有测试数据集之类的东西?——问题来源于 Elasticsearch 中文社区https://elasticsearch.cn/question/13129 2…

解决VSCode使用SSH远程连接时无法指定用户名的问题

Windows 11自带OpenSSH客户端,和VSCode配合得很好,没有这个问题。 今天要说的是旧版本Windows 7/8/10系统遇到的问题。 PS: Windows 7可以运行的最后版本是VSCode 1.80.2 由于Windows 7/8/10没有自带的OpenSSH客户端,但可以调用MSYS环境下的…

python图像处理 ——几种图像增强技术

图像处理 ——几种图像增强技术 前言一、几种图像增强技术1.直方图均衡化2.直方图适应均衡化3.灰度变换4.同态滤波5.对比拉伸6.对数变换7.幂律变换(伽马变换) 前言 图像增强是指通过各种算法和技术,改善或提高数字图像的质量、清晰度、对比度…

3.22每日一题(二重积分求平面区域面积)

先复习求平面积分的公式 注:面对平面积分直接使用二重积分对1求积分即可;所以只需要背二重积分的两个公式: 1、直角坐标下对1积分 2、极坐标下对1积分 xy-1是等轴双曲线!! 1、先画图定区域 2、选择先对x积分还是先对…

深度学习之基于Yolov5闯红灯及红绿灯检测系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、闯红灯及红绿灯检测系统![请添加图片描述](https://img-blog.csdnimg.cn/8f260c2ed5ed4d8596e27d38abe42745.jpeg)四. 总结 一项目简介 基于Y…

力扣 upper_bound 和 lower_bound

👨‍🏫 34. 在排序数组中查找元素的第一个和最后一个位置 🌸 AC code 2023版 class Solution {public int[] searchRange(int[] nums, int target) {int[] res { -1, -1 };if(nums.length 0)return res;int l 0;int r nums.length - 1;…
最新文章