LeetCode662.设计循环队列||4种方法实现
目录
题目
思路1(链表)
代码
思路2(数组)
代码
题目
题目要求的队列需要实现的功能有
①Creat---设置队列长度
②Front---获取队列头
③Rear---获取队列尾
④en----插入元素
⑤de---删除元素
⑥empty---判空
⑦full---判满
思路1(链表)
🔍普通队列长度没有限制,循环队列的长度是初始化时被规定的。
❓ 请思考:普通的队列我们可以通过链表来实现,那么环状的队列能否继续通过链表实现呢?
💡答案:可以,需要将链表设计为循环链表。🔑解析:这样可以通过最后一个链表节点找到第一个链表节点。
❓请思考:怎么通过循环链表构造循环队列呢?
构造出一个循环链表,定义front指向队列头,定义back指向队列尾后一个空间。规定front==back时队列为空。
🔨插入4个元素
❗注意:此时不能继续插入元素了,如果在插入元素,back接下来就和front一样,而这是我们之前定义队列为空的条件。也就是说:在前提条件front==back表示队列为空时,循环链表有5个节点,只能存储4个数据,推而广之,如果想要队列中存放k个数据,那么循环链表需要定义(k+1)个节点。
🔨删除元素:删除队列头只需要将链表头删即可。
❗注意:🚫头删不要将需要删除数据所在的空间释放,这样可能会导致下次插入元素时非法访问内存空间。头删只需要让front指向下一个空间即可。front和back之间的数据才是队列中的元素。
❓请思考:怎么找到队列尾?
💡解决方案:
①循环队列结构中添加一个preTail指针,指向链表尾节点的前一个结点。
②遍历整个链表,在链表尾节点的前一个节点时停止遍历。
③使用双向循环链表。
三种方案大同小异,这里不在赘述
代码
💬方案1代码
//使用链表实现循环队列
typedef struct Qnode
{struct Qnode* next;int val;
}Qnode;
typedef struct MyCircularQueue{Qnode* head;Qnode* tail;Qnode* preTail;int size;int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));q->size = 0;q->capacity = k;//创建第一个空间q->head = (Qnode*)malloc(sizeof(Qnode));q->tail = q->head;q->preTail = NULL;Qnode* cur = q->head;//创建k个节点while (k--){cur->next = (Qnode*)malloc(sizeof(Qnode));cur = cur->next;}cur->next = q->head;return q;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//队列满了插入失败if (obj->tail->next == obj->head)return false;//插入数据obj->tail->val = value;obj->preTail = obj->tail;obj->tail = obj->tail->next;obj->size++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {//队列为空删除失败if (obj->size == 0)return false;//链表头删(不要销free节点的空间)obj->head = obj->head->next;obj->size--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->head->val;
}int myCircularQueueRear(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->preTail->val;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->size == 0;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->size == obj->capacity;
}void myCircularQueueFree(MyCircularQueue* obj) {//需要释放k+1个节点int cnt = obj->capacity + 1;Qnode* cur = obj->head;while (cnt--){Qnode* tmp = cur->next;free(cur);cur = tmp;}free(obj);
}
💬方案2代码
//使用链表实现循环队列
typedef struct Qnode
{struct Qnode* next;int val;
}Qnode;
typedef struct MyCircularQueue{Qnode* head;Qnode* tail;int size;int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));q->size = 0;q->capacity = k;//创建第一个空间q->head = (Qnode*)malloc(sizeof(Qnode));//tail==front,初始化为空q->tail = q->head;Qnode* cur = q->head;//创建k个节点while (k--){cur->next = (Qnode*)malloc(sizeof(Qnode));cur = cur->next;}cur->next = q->head;return q;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//队列满了插入失败if (obj->size == obj->capacity)return false;//插入数据obj->tail->val = value;obj->tail = obj->tail->next;obj->size++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {//队列为空删除失败if (obj->size == 0)return false;//链表头删(不要销free节点的空间)obj->head = obj->head->next;obj->size--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->head->val;
}int myCircularQueueRear(MyCircularQueue* obj) {if (obj->size == 0)return -1;//遍历链表Qnode* cur = obj->head;while (cur->next != obj->tail){cur = cur->next;}return cur->val;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->size == 0;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->size == obj->capacity;
}void myCircularQueueFree(MyCircularQueue* obj) {//需要释放k+1个节点int cnt = obj->capacity + 1;Qnode* cur = obj->head;while (cnt--){Qnode* tmp = cur->next;free(cur);cur = tmp;}free(obj);
}
💬方shu'zu案3代码
//使用链表实现循环队列
typedef struct Qnode
{struct Qnode* next;struct Qnode* pre;int val;
}Qnode;
typedef struct MyCircularQueue{Qnode* head;Qnode* tail;int size;int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));q->size = 0;q->capacity = k;//创建第一个空间q->head = (Qnode*)malloc(sizeof(Qnode));//tail==front,初始化为空q->tail = q->head;Qnode* cur = q->head;//创建k个节点while (k--){Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));cur->next = newnode;newnode->pre = cur;cur = cur->next;}cur->next = q->head;q->head->pre = cur;return q;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//队列满了插入失败if (obj->size == obj->capacity)return false;//插入数据obj->tail->val = value;obj->tail = obj->tail->next;obj->size++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {//队列为空删除失败if (obj->size == 0)return false;//链表头删(不要销free节点的空间)obj->head = obj->head->next;obj->size--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->head->val;
}int myCircularQueueRear(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->tail->pre->val;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->size == 0;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->size == obj->capacity;
}void myCircularQueueFree(MyCircularQueue* obj) {//需要释放k+1个节点int cnt = obj->capacity + 1;Qnode* cur = obj->head;while (cnt--){Qnode* tmp = cur->next;free(cur);cur = tmp;}free(obj);
}
思路2(数组)
❓先思考:通过数组实现的环形队列有哪些成员?
🔑数组、队列头下标、队列尾下标、队列元素个数、队列最大容量。
我们规定头下标和尾下标相等时队列为空。
📚来看数组模拟循环队列示意图(队列的容量是5):
①🔨队列为空
②🔨入队
③🔨出队
④🔨入队
❗注意:从上述过程中可以观察到:在物理结构中 ,队尾可能在队头的前面也可能在队头后面。
🔺思维导图:
代码
typedef struct {int* a;//a指向数组int front;//头下标int back;//尾下标int size;//队列元素个数int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));q->a = (int*)malloc(sizeof(int) * (k + 1));q->size = 0;q->capacity = k;q->front = q->back = 0;return q;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//队列已满if (obj->size == obj->capacity)return false;obj->a[obj->back] = value;obj->back++;//尾下标越界归0if (obj->back > obj->capacity){obj->back = 0;}obj->size++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if (obj->size == 0)return false;obj->front++;//头下标越界归0if (obj->front > obj->capacity)obj->front = 0;obj->size--;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {return obj->size == 0 ? -1 : obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {//空队列if (obj->size == 0)return -1;if (obj->back == 0){return obj->a[obj->capacity];}return obj->a[obj->back - 1];
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->size == 0;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return obj->size == obj->capacity;
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}
相关文章:

LeetCode662.设计循环队列||4种方法实现
目录 题目 思路1(链表) 代码 思路2(数组) 代码 题目 题目要求的队列需要实现的功能有 ①Creat---设置队列长度 ②Front---获取队列头 ③Rear---获取队列尾 ④en----插入元素 ⑤de---删除元素 ⑥empty---判空 ⑦full---判满 思路1(链表) 🔍普通队列长度没有限制&…...
人工智能专栏第十二讲——依存解析
依存句法分析是一种自然语言处理技术,其目的是识别句子中单词之间的依赖关系。在自然语言处理中,依存句法分析是一项非常重要的任务,因为它可以帮助我们理解句子的语义结构,从而更好地进行文本分析、信息抽取、语音识别等任务。 …...

nest日志包pino、winston配置-懒人的折腾
nest日志 三种node服务端日志选型 winstonpinolog4js 2023年5月23日 看star数:winston > pino > log4js 使用体验: pino 格式简洁,速度快,支持输入日志到任意数据库,日志暂无自动清理(可能是我…...

一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入
引言 增值税发票识别OCR API是一项重要的技术创新,它在如今信息化的商业环境中发挥着重要作用。通过利用该API,企业和机构能够实现增值税发票的自动化识别和信息提取,从而在财务管理、票据核对、报销流程等方面带来许多好处。 本文将详细介…...

消息队列对比
目录 什么是消息队列 常用的消息队列工具对比 1 、ActiveMQ 2 、RabbitMQ 3、Kafka 4、 RocketMQ 什么是消息队列 消息队列是分布式应用间交换信息的重要组件,消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列࿰…...
Ceph对象存储的基本概念,使用以及优点
Ceph对象存储的基本概念,使用以及优点 Ceph是一种基于分布式架构的对象存储系统,它可以提供高可靠性、高扩展性和高性能的存储服务。这种存储系统可以用于处理大量的数据,例如大型数据库、云存储、视频流、图像数据等。Ceph对象存储系统的基…...

工业互联网UWB定位系统源码,支持自定义开发
工厂人员定位系统,采用UWB定位技术,通过在厂区内部署一定数量的定位基站,以及为人员、车辆、物资佩戴标签卡的形式,实时获取人员精确位置,精度高达10cm。 文末获取联系 工厂人员定位系统可实现物资/车辆实时定位&#…...
VIC模型教程
详情点击链接:RVIC模型融合实践技术应用及未来气候变化模型预测 一:VIC模型的原理与特点 1.VIC模型各模块的主要原理 2.VIC模型的特点及优势 3.VIC模型的适用范围及其限制 4.VIC模型主要输入和输出文件解析案例一 :基于QGIS的VIC模型建模…...

软件著作权容易搞吗?
没有代码、材料,只有一个软件名字就能拿证,你说容易不… 当然这是对我们软著一级代理来说,每年申请下证几千个软著。下面说说下证要点给大家避坑。人群覆盖高新企业、大学生、大学老师、互联网公司。 软件著作权想要轻松下证,必…...
Mac打出特殊字符
optionq:œ ---------optionw:∑ optione: ---------optionr: optiont:† ---------optiony: optionu: ---------optionI:无 optiono: ---------optionP:π o…...
java设计模式之单例设计模式的前世今生
单例设计模式是什么? 单例设计模式是一种创建型模式,它保证一个类只有一个实例,并且该实例提供了全局访问点。这意味着即使在不同的地方,访问这个单例实例的代码得到的都是同一个对象。 单例模式的特点如下: - 保证…...

小航助学2023年3月GESP_C++一级试卷(含题库答题软件账号)
GESP在线模拟训练系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级(2019年3月)在线答题_程序猿下山的博客-CSDN博客_小航答题助手 答案:B 第1题以下不属于计算机输入设备的有( )。 A、键盘B、音箱C、鼠标D、传感器 …...

好程序员:女生学Java好学吗?女生学Java有什么优势?
小源经常会听到女生咨询适不适合学习Java开发的问题,提出这种问题归根结底还是缺乏性别自信,默认女性比男性弱。实际上这个问题并不存在,男女平等才是正确的思维,当然,也为了解开女生们的心结,这里好程序员…...

为Eclipse安装lombok插件
原生的Eclipse没有lombok插件,即使项目引入了lombok依赖也无法正常使用Data等常用标签。下面介绍一下如何手动为Eclipse添加lombok插件,具体操作步骤如下: (1)打开Download地址,点击页面中间的超链接下载最…...
spring-boot 实现接口转发服务,同时支持get 和 post等多种请求
spring-boot 实现接口转发服务,同时支持get 和 post等多种请求 (1)新建类:ProxyController.java package com.taobao.product.controller;import com.taobao.framework.HttpResult; import io.swagger.annotations.Api; import …...
About JDKFlightRecorder--人工翻译
JFR是什么 JDK Flight Recorder是一个工具,用于收集有关JVM以及在JVM上运行的Java程序的诊断和分析数据。 集成到Java虚拟机(JVM)中,使用默认设置时,性能影响小于1%。几乎不产生性能开销,因此即使在负载很…...

【计算机系统基础3】数据的存储与运算
【计算机系统基础3】数据的存储与运算 3.程序调试与实践:数据存储与运算3.1真值与机器数3.1.1整数的编码 3.2数据的存储3.3数组的对齐3.4数据类型的转换3.4.1整数之间的数据类型转换3.4.2整数与浮点数之间的转换3.4.3自动类型转换 3.5浮点数的表示和运算--IEEE 7543…...

【算法】快速排序
目录 核心思想: 过程: 演示: 第一趟: 第二趟: 代码: 核心思想: 从待排序列中取一个元素作为中心,所有比它小或相等的元素一律放在前面, 所有比它大的元素放在后面&…...

【移动端网页布局】流式布局案例 ③ ( 实现搜索栏功能 | 伪元素选择器 | 子绝父相 | 外边距塌陷处理 | 二倍精灵图处理方案 )
文章目录 一、搜索栏样式及核心要点1、实现效果2、自动伸缩搜索栏实现3、搜索栏父容器设置4、搜索栏左右两侧的按钮盒子5、搜索栏盒子6、二倍精灵图处理方案 二、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、搜索栏样式及核心要点 1、实现效果 上一篇博客中 , 完成…...

【C++修炼之路】30.可变参数模板包装器
每一个不曾起舞的日子都是对生命的辜负 C11之可变参数模板&&包装器 前言一.可变参数模板的首次登场二.参数包展开2.1 递归函数方式展开参数包2.2 逗号表达式展开参数包 三.容器的emplace方法四.包装器4.1 什么是function4.2 function包装器的作用4.3 function的实际用途…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...