当前位置: 首页 > news >正文

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 什么是消息队列 消息队列是分布式应用间交换信息的重要组件,消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列&#xff0…...

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的实际用途…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

golang循环变量捕获问题​​

在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下: 问题背景 看这个代码片段: fo…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...