设计循环队列(详解)
呀哈喽,我是结衣
今天给大家带来的内容如标题所述,我们来设计环形队列,虽然队列没有讲,但是我就是想讲啊。那么环形队列现在开始。
队列的属性
在设计环形队列前,我们先要了解队列的特点(先进先出),就想现实中我们排队一样,先到的人先得。所以现实中银行的取票机是可以用队列实现的。
循环队列
本次讲解是基于leetcode的以题来讲解的,贴张图给大家介绍吧:

看完题目不知道大家有没有思路呢?没有的话就听我详细的解释吧。
顺序表or链表
看完题目你最先想到的实现方法是顺序表还是链表呢?倒不是说这两种方法只能选择一个,而是实现难易程度问题,你觉得用顺序表难还是用链表难呢?这里我选择用顺序表来讲解,我觉得顺序表简单一些呢。
顺序表实现循环队列
在实现之前我们来看看题目要我们实现的功能吧:
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) {}

了解完要求下面我们就要分析了。
怎样实现循环
首先我们要定义一个头和尾。(front和back)他们就是下标哈。
有了头和尾。我们要把他们的初始值给多少呢,都给‘0’还是给‘-1’呢,这里我的做法是把头和尾都给‘0’,你可能会说那如果插入了一个数,back怎么办。哼哼,我们把back++,我们让back指向的最后一个数的下一个,而非最后一个数,那么新的问题又来了,当出现这种情况怎么办。

back不就出去了吗,是的,我们要解决这个问题就要多定义一个空间,题目让我们定义k个空间,我们就要定义k+1个空间。但是有一个空间是不存储数据的。

在k+1个空间中始终有一个空间是不存储数据的只有这样才能满足题目要求的k个空间。

这就是循环的示意图,当前面有空间,又要插入数据时,在back的位置上插入数据后再将back = 0。
结构体的创建
typedef struct {int* data;int front;int back;int k;
} MyCircularQueue;
相信看完上面的简介这个结构体的创建是没有问题的吧。
函数的实现
这里的函数的实现并不是按照题目顺序来进行的。因为这里的函数也可以相互的调用为后续节省时间。
初始化
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));tmp->data = (int*)malloc(sizeof(int) * (k + 1));tmp->front = 0;tmp->back = 0;tmp->k = k;return tmp;
}
我们先要malloc一个结构体的空间,然后再malloc tmp->data这个数组的大小,因为我们有一个空位置所以就开了k+1个的空间。还有头和尾的赋值尾‘0’,在上面的实现循环里有讲解。
队列判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if (obj->back == obj->front){return true;}return false;
}
这个代码就很直观了,back == front就直接判空了。因为我们这里的back是不会有数据的,出现这种情况这样最初的时候在那种情况就是队列为空的情况。
队列判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {if ((obj->back + 1) % (obj->k + 1) == obj->front){return true;}return false;
}
我们都知道当back的下一个为front的时候就是满的时候,所以写成back+1 == front是不是就可以了呢?不是不行,多加个判断就可以了,但是为我们要介绍的方法取余的方法,在这种循环中就特别的好用,利用的就是当被除数比除数小的时候余数为被除数。
数据插入
写完判空判满的函数,我们下面就会轻松一些
要插入数据我们首先就是要判断队列有没有满,如果满了就不能插入,并且返回false
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if (myCircularQueueIsFull(obj)){return false;}obj->data[obj->back] = value;if (obj->back == obj->k)obj->back = 0;elseobj->back++;return true;
}
除了判满,我们还要小心当back在最后的情况下,在最后的话如果我们还是back++的话,back就出界了,后果可是很严重的,后面返回为数据的时候就可能会访问野指针。导致程序崩溃。所以我们就要加判断呢。
数据删除
删除数据的时候我们要知道队列不能为空,为空就不能删除,返回false。
bool myCircularQueueDeQueue(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return false;}if (obj->front == obj->k)obj->front = 0;elseobj->front++;return true;
}
当然后面判断和前面插入的时候相似,front在最后的时候就不能++了,要让他等于0。
返回头
不能为空
int myCircularQueueFront(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}return obj->data[obj->front];
}
返回尾
不能为空的同时还要注意,back为0的时候,如果你还 减减 不久变成负数了吗,这样肯定是不行的,所以我们要再加一个判断咯。
int myCircularQueueRear(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}if (obj->back == 0)return obj->data[obj->k];elsereturn obj->data[obj->back - 1];
}
销毁
void myCircularQueueFree(MyCircularQueue* obj) {free(obj);obj = NULL;
}
销毁就是十分的简单
循环队列代码
typedef struct {int* data;int front;int back;int k;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));tmp->data = (int*)malloc(sizeof(int) * (k + 1));tmp->front = 0;tmp->back = 0;tmp->k = k;return tmp;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if (obj->back == obj->front){return true;}return false;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {if ((obj->back + 1) % (obj->k + 1) == obj->front){return true;}return false;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if (myCircularQueueIsFull(obj)){return false;}obj->data[obj->back] = value;if (obj->back == obj->k)obj->back = 0;elseobj->back++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return false;}if (obj->front == obj->k)obj->front = 0;elseobj->front++;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}return obj->data[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}if (obj->back == 0)return obj->data[obj->k];elsereturn obj->data[obj->back - 1];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj);obj = NULL;
}
完

相关文章:
设计循环队列(详解)
呀哈喽,我是结衣 今天给大家带来的内容如标题所述,我们来设计环形队列,虽然队列没有讲,但是我就是想讲啊。那么环形队列现在开始。 队列的属性 在设计环形队列前,我们先要了解队列的特点(先进先出&#x…...
【Python】Vscode解决Python中制表符和空格混用导致的缩进问题
【Python】Vscode解决Python中制表符和空格混用导致的缩进问题 文章目录 【Python】Vscode解决Python中制表符和空格混用导致的缩进问题1. 问题来源2. 解决Reference 1. 问题来源 在python中使用缩进来进行代码块的分区,通常来说python的一个缩进包含4个空格&#…...
CocosCreator 面试题(十六)Cocos Creator 节点池的基本原理是什么?如何使用?
一、Cocos Creator 节点池的基本原理是什么? Cocos Creator 是一个游戏开发引擎,它提供了节点池(Node Pool)的功能,用于管理和重用游戏中的节点对象。节点池的基本原理如下: 创建初始节点:在游戏…...
VUE留言板
效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>作业</title><styl…...
【办公软件】电脑开机密码忘记了如何重置?
这个案例是家人的电脑,已经使用多年,又是有小孩操作过的,所以电脑密码根本不记得是什么了?那难道这台电脑就废了吗?需要重新装机吗?那里面的资料不是没有了? 为了解决以上问题,一般…...
PTA NeuDS-数据库题目集
一.判断题 1.在数据库中产生数据不一致的根本原因是冗余。T 解析:数据冗余是数据库中产生数据不一致的根本原因,因为当同一数据存储在多个位置时,如果其中一个位置的数据被修改,其他位置的数据就不一致了。因此,在数据…...
Redis深入理解-内核请求处理流程、数据传输协议
Redis 内核级请求处理流程 Redis Server 其实就是 Linux 服务器中的一个进程 主要还是下图的流程 应用先和 server 端建立 TCP 连接建立连接之后,server 端就会有一个与该客户端通信的 socket,客户端的读写请求发送到服务端的 socket那么通过 IO 多路…...
Mac电脑卸载/删除nodejs
使用命令行卸载 Node.js 第一步:打开终端,输入以下命令显示 Node.js 的安装路径: which node执行该命令后,会显示安装路径: /usr/local/bin/node第二步:输入以下命令删除 Node.js 相关的文件:…...
C语言之内存函数
C语言之内存函数 文章目录 C语言之内存函数1. memcpy 使⽤和模拟实现1.1 memcpy 函数的使用1.3 memcpy的模拟实现 2. memmove 使⽤和模拟实现2.1 memmove 函数的使用2.2 memmove的模拟实现 3. memset 函数的使用4. memcmp 函数的使⽤ 1. memcpy 使⽤和模拟实现 函数声明如下&a…...
基本数据结构二叉树(1)
目录 1.树概念及结构 1.1树的概念 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用(表示文件系统的目录树结构) 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树: 2.3 特殊的二叉树: 2.5 二叉树的存储结构 2. 链式存…...
【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】
👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…...
Android:Google三方库之Adjust集成详细步骤
通过 Adjust 安卓 SDK,您可以在自己的安卓应用中跟踪归因、事件及更多数据。请按照本指南中说明的步骤操作,在应用内设置 Adjust SDK 1、添加依赖 //adjustimplementation("com.adjust.sdk:adjust-android:4.33.5")implementation("com.…...
prometheus|云原生|grafana-9.4.3版本的主题更改
一, grafana-9.4.3版本的主题更改 grafana-9.4.3版本应该是目前比较高的版本了,但不知道是什么原因,grafana的主题界面并不多,只有暗色,亮色和系统色三种 配置管理----首选项里可以看到 亮色: 暗色&…...
B033-Servlet交互 JSP
目录 ServletServlet的三大职责跳转:请求转发和重定向请求转发重定向汇总请求转发与重定向的区别用请求转发和重定向完善登录 JSP第一个JSP概述注释设置创建JSP文件默认字符编码集 JSP的java代码书写JSP的原理三大指令九大内置对象改造动态web工程进行示例内置对象名…...
Less 安装教程
文章目录 前言LESS的系统要求安装LESS例子输出Less编译css工具后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:Sass和Less 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板…...
Java研学-多线程
一 名词解析 1 线程 : 控制指定APP(进程)执行的最基本单元(最小单位) 2 进程 : 硬件设备上的每一个应用程序 3 单线程 : 一个进程中只有一个线程执行,实际上基本没有这种情况 4 多线程 : 一个进程中至少有两个或两个以上的线程在执行 二 创建方式 1 共有三种:Thread类. R…...
【日常总结】如何禁止浏览器 http自动跳转成https
一、场景 二、问题 三、解决方案 3.1 chrome 浏览器 3.2 edge 浏览器: 3.3 Safari 浏览器 3.4 Firefox 浏览器 3.5 Microsoft Edge 一、场景 公司网站 http:// 谷歌浏览器中自动转换成 https:// 导致无法访问 二、问题 nginx配置ssl 443接口, ht…...
文本转语音:微软语音合成标记语言 (SSML) 文本结构和事件
SSML 的语音服务实现基于万维网联合会的语音合成标记语言版本 1.0。 语音服务支持的元素可能与 W3C 标准不同。 每个 SSML 文档是使用 SSML 元素(或标记)创建的。 这些元素用于调整语音、风格、音节、韵律、音量等。 下面是 SSML 文档的基本结构…...
计算机网络之物理层(数据通信有关)
一、概述 1.1物理层引入的目的 屏蔽掉传输介质的多样性,导致数据传输方式的不同;物理层的引入使得高层看到的数据都是统一的0,1构成的比特流 1.2.物理层如何实现屏蔽 物理层靠定义的不同的通信协议(一般称通信规程) 这些协议…...
安卓开发之HTTP API服务接口设计(基于okhttp3请求)
安卓中的请求 OkHttp3 是一个开源的 Java/Android HTTP 客户端库,由 Square 公司开发。它提供了简洁和高效 的 API ,用于进行 HTTP 请求、处理响应以及与服务器进行通信。 以下是 OkHttp3 的一些主要特点和功能: 简单易用: OkHttp3 提供了简洁的 API ,使得发送 HTTP 请求变…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
