【10.2】队列-设计循环队列
一、题目
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 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
提示:
- 所有的值都在 0 至 1000 的范围内;
- 操作数将在 1 至 1000 的范围内;
- 请不要使用内置的队列库。
二、解题思路
2.1 数组实现
我们可以通过数组来模拟循环队列,利用数组的索引构建一个虚拟的环形结构。在循环队列中,设置两个指针:队尾 `rear` 和队首 `front`,队列的大小是固定的。结构如下图所示:

在循环队列中,当队列为空时,`front` 和 `rear` 相等,即 `front == rear`;而当队列的所有空间都被占满时,同样会出现 `front == rear` 的情况。为了区分这两种状态,我们规定队列的数组容量为 `capacity`,但循环队列最多只能存储 `capacity - 1` 个元素。当队列中只剩下一个空闲的存储单元时,就认为队列已满。因此,队列判空的条件是 `front == rear`,而判满的条件是 `front == (rear + 1) % capacity`。
对于一个固定大小的数组,只要知道队尾 `rear` 和队首 `front`,就可以计算出队列的当前长度: (rear - front + capacity) mod capacity
循环队列的主要属性如下:
**`elements`**:一个固定大小的数组,用于存储循环队列的元素。
**`capacity`**:循环队列的容量,即队列中最多可以容纳的元素数量。
**`front`**:队首元素在数组中的索引。
**`rear`**:队尾元素的下一个位置的索引。
循环队列的接口方法如下:
**`MyCircularQueue(int k)`**:初始化队列,数组的空间大小为 `k + 1`,并将 `front` 和 `rear` 初始化为 0。
**`enQueue(int value)`**:在队列的尾部插入一个元素,并将 `rear` 更新为 `(rear + 1) % capacity`。
**`deQueue()`**:从队首取出一个元素,并将 `front` 更新为 `(front + 1) % capacity`。
**`Front()`**:返回队首的元素,需要先检测队列是否为空。
**`Rear()`**:返回队尾的元素,需要先检测队列是否为空。
**`isEmpty()`**:检测队列是否为空,只需判断 `rear` 是否等于 `front`。
**`isFull()`**:检测队列是否已满,只需判断 `front` 是否等于 `(rear + 1) % capacity`。
通过这种方式,循环队列能够高效地利用数组空间,同时避免普通队列在空间利用上的不足。
#include <iostream>
#include <vector>
using namespace std;class MyCircularQueue {
private:int front; // 队首指针int rear; // 队尾指针int capacity; // 队列容量vector<int> elements; // 用于存储队列元素的数组public:// 构造函数,初始化队列MyCircularQueue(int k) {this->capacity = k + 1; // 容量为 k + 1,多分配一个空间用于区分空和满状态this->elements = vector<int>(capacity); // 初始化数组rear = front = 0; // 初始化队首和队尾指针}// 向循环队列插入一个元素bool enQueue(int value) {if (isFull()) {return false; // 队列已满,插入失败}elements[rear] = value; // 将元素插入队尾rear = (rear + 1) % capacity; // 更新队尾指针(循环)return true;}// 从循环队列中删除一个元素bool deQueue() {if (isEmpty()) {return false; // 队列为空,删除失败}front = (front + 1) % capacity; // 更新队首指针(循环)return true;}// 获取队首元素int Front() {if (isEmpty()) {return -1; // 队列为空,返回 -1}return elements[front]; // 返回队首元素}// 获取队尾元素int Rear() {if (isEmpty()) {return -1; // 队列为空,返回 -1}return elements[(rear - 1 + capacity) % capacity]; // 返回队尾元素(处理循环情况)}// 检查队列是否为空bool isEmpty() {return rear == front; // 队首和队尾指针相等时,队列为空}// 检查队列是否已满bool isFull() {return ((rear + 1) % capacity) == front; // 队尾的下一个位置是队首时,队列已满}
};int main() {// 创建循环队列,容量为 3MyCircularQueue circularQueue(3);// 测试 enQueue 操作cout << "enQueue(1): " << circularQueue.enQueue(1) << endl; // 输出: 1 (true)cout << "enQueue(2): " << circularQueue.enQueue(2) << endl; // 输出: 1 (true)cout << "enQueue(3): " << circularQueue.enQueue(3) << endl; // 输出: 1 (true)cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 输出: 0 (false,队列已满)// 测试 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 输出: 3// 测试 isFull 操作cout << "isFull(): " << circularQueue.isFull() << endl; // 输出: 1 (true)// 测试 deQueue 操作cout << "deQueue(): " << circularQueue.deQueue() << endl; // 输出: 1 (true)// 测试 enQueue 操作cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 输出: 1 (true)// 测试 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 输出: 4// 测试 Front 操作cout << "Front(): " << circularQueue.Front() << endl; // 输出: 2// 测试 isEmpty 操作cout << "isEmpty(): " << circularQueue.isEmpty() << endl; // 输出: 0 (false)return 0;
}
复杂度分析
-
时间复杂度:初始化和每项操作的时间复杂度均为 O(1)。
-
空间复杂度:O(k),其中 k 为给定的队列元素数目。
2.2 链表实现
我们也可以使用链表来实现队列。与数组相比,链表实现队列更加灵活,因为链表可以在 O(1)时间复杂度内完成元素的插入和删除操作。具体来说,入队操作是将新元素插入到链表的尾部,而出队操作则是返回链表的头节点,并将头节点指向下一个节点。
循环队列的属性如下:
-
head:链表的头节点,表示队列的头部。 -
tail:链表的尾节点,表示队列的尾部。 -
capacity:队列的容量,即队列可以存储的最大元素数量。 -
size:队列当前存储的元素数量。
通过链表实现循环队列,可以避免数组实现中需要处理索引循环的问题,同时也能高效地完成队列的基本操作。
#include <iostream>
using namespace std;// 链表节点定义
struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {}
};class MyCircularQueue {
private:ListNode *head; // 队首指针,指向链表的头节点ListNode *tail; // 队尾指针,指向链表的尾节点int capacity; // 队列的容量int size; // 队列当前的大小public:// 构造函数,初始化队列MyCircularQueue(int k) {this->capacity = k; // 设置队列容量this->size = 0; // 初始化队列大小为 0this->head = nullptr; // 初始化队首指针为空this->tail = nullptr; // 初始化队尾指针为空}// 向队列尾部插入一个元素bool enQueue(int value) {if (isFull()) {return false; // 队列已满,插入失败}ListNode *node = new ListNode(value); // 创建新节点if (!head) {head = tail = node; // 如果队列为空,新节点既是队首也是队尾} else {tail->next = node; // 将新节点链接到队尾tail = node; // 更新队尾指针}size++; // 队列大小加 1return true;}// 从队列头部删除一个元素bool deQueue() {if (isEmpty()) {return false; // 队列为空,删除失败}ListNode *node = head; // 保存队首节点head = head->next; // 更新队首指针size--; // 队列大小减 1delete node; // 释放队首节点的内存if (isEmpty()) {tail = nullptr; // 如果队列为空,更新队尾指针为空}return true;}// 获取队首元素int Front() {if (isEmpty()) {return -1; // 队列为空,返回 -1}return head->val; // 返回队首节点的值}// 获取队尾元素int Rear() {if (isEmpty()) {return -1; // 队列为空,返回 -1}return tail->val; // 返回队尾节点的值}// 检查队列是否为空bool isEmpty() {return size == 0; // 队列大小为 0 时为空}// 检查队列是否已满bool isFull() {return size == capacity; // 队列大小等于容量时为满}
};int main() {// 创建循环队列,容量为 3MyCircularQueue circularQueue(3);// 测试 enQueue 操作cout << "enQueue(1): " << circularQueue.enQueue(1) << endl; // 输出: 1 (true)cout << "enQueue(2): " << circularQueue.enQueue(2) << endl; // 输出: 1 (true)cout << "enQueue(3): " << circularQueue.enQueue(3) << endl; // 输出: 1 (true)cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 输出: 0 (false,队列已满)// 测试 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 输出: 3// 测试 isFull 操作cout << "isFull(): " << circularQueue.isFull() << endl; // 输出: 1 (true)// 测试 deQueue 操作cout << "deQueue(): " << circularQueue.deQueue() << endl; // 输出: 1 (true)// 测试 enQueue 操作cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 输出: 1 (true)// 测试 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 输出: 4// 测试 Front 操作cout << "Front(): " << circularQueue.Front() << endl; // 输出: 2// 测试 isEmpty 操作cout << "isEmpty(): " << circularQueue.isEmpty() << endl; // 输出: 0 (false)return 0;
}
复杂度分析
-
时间复杂度:初始化和每项操作的时间复杂度均为 O(1)。
-
空间复杂度:O(k),其中 k 为给定的队列元素数目。
相关文章:
【10.2】队列-设计循环队列
一、题目 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普…...
设置jmeter界面图标字体大小
设置jmeter界面图标字体大小 方法:点击“选项” -> 点击放大、缩小。(可进行全局的菜单、左侧目录结构树、元件界面显示等字体图标的放大、缩小。)...
Xposed-Hook
配置 Xposed 模块的 AndroidManifest.xml: <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"your.package.name"><applicationandr…...
设计模式Python版 原型模式
文章目录 前言一、原型模式二、原型模式示例三、原型管理器 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对…...
QT:图像上绘制图形
需求描述 1、展示一张图像 2、在图像上可以使用数据绘制图像:矩形、不规则图形、线条 3、有按键可以选择 概要设计 规划布局如下 1、左边是Qlabel 用于展示图片 2、右边是三个按钮 具体实现 1、 首先设计 UI 界面,对控件进行布局 在 mainwindow.u…...
GPU上没程序在跑但是显存被占用
原因:存在僵尸线程,运行完但是没有释放内存 查看僵尸线程 fuser -v /dev/nvidia*关闭僵尸线程 pkill -9 -u 用户名 程序名 举例:pkill -9 -u grs python参考:https://blog.csdn.net/qq_40206371/article/details/143798866...
wordpress代码结构解析
WordPress 是一个基于 PHP 和 MySQL 的开源内容管理系统(CMS),广泛用于构建网站和博客。要解析 WordPress 代码,首先需要了解其核心结构、主要文件和常用的函数。以下是 WordPress 代码解析的基本指南: --- ### 1. *…...
【Unity3D】实现2D小地图效果
目录 一、玩家脚本Player 二、Canvas组件设置 三、小地图相关 四、GameLogicMap脚本修改 基于:【Unity3D】Tilemap俯视角像素游戏案例-CSDN博客 2D玩家添加Dotween移动DOPath效果,移动完成后进行刷新小地图(小地图会顺便刷新大地图&…...
关联传播和 Python 和 Scikit-learn 实现
文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数:集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…...
https数字签名手动验签
以bing.com 为例 1. CA 层级的基本概念 CA 层级是一种树状结构,由多个层级的 CA 组成。每个 CA 负责为其下一层级的实体(如子 CA 或终端实体)颁发证书。层级结构的顶端是 根 CA(Root CA),它是整个 PKI 体…...
LeetCode:62.不同路径
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:62.不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” &…...
如果我想设计一款复古风格的壁纸,应该选什么颜色?
设计复古风格的壁纸时,选择合适的颜色是营造怀旧和经典氛围的关键。复古风格通常使用一些温暖、柔和且带有岁月痕迹的色调。以下是一些适合复古风格壁纸的颜色选择和搭配建议: 一、复古风格的主色调 棕色系: 特点:棕色是复古风格的…...
【数据结构】树的基本:结点、度、高度与计算
树是数据结构中一种重要的非线性结构,广泛应用于计算机科学的各个领域,例如文件系统、数据库索引、编译器等。理解树的各种性质,如结点数、度、高度等,对于解决实际问题至关重要。 本文将会探讨树的基本概念,以及给出几…...
【Pytest】生成html报告中,中文乱码问题解决方案
链接上一篇文章:https://blog.csdn.net/u013080870/article/details/145369926?spm1001.2014.3001.5502 中文乱码问题,python3,Python3.7后,还一个文件就是result.py 因为中文可以在内容中,也可能在文件名,类名&…...
week08_文本匹配任务
1、文本匹配任务概述 狭义: 给定一组文本,判断其是否语义相似 今天天气不错 match 今儿个天不错呀 √ 今天天气不错 match 你的代码有bug 以分值形式给出相似度 今天天气不错 match 今儿个天不错呀 0.9 今天天气不错 match…...
JUC--ConcurrentHashMap底层原理
ConcurrentHashMap底层原理 ConcurrentHashMapJDK1.7底层结构线程安全底层具体实现 JDK1.8底层结构线程安全底层具体实现 总结JDK 1.7 和 JDK 1.8实现有什么不同?ConcurrentHashMap 中的 CAS 应用 ConcurrentHashMap ConcurrentHashMap 是一种线程安全的高效Map集合…...
【2024年华为OD机试】(C卷,200分)- 推荐多样性 (JavaScriptJava PythonC/C++)
一、问题描述 问题描述 我们需要从多个已排序的列表中选取元素,以填充多个窗口。每个窗口需要展示一定数量的元素,且元素的选择需要遵循特定的穿插策略。具体来说,我们需要: 从第一个列表中为每个窗口选择一个元素,然后从第二个列表中为每个窗口选择一个元素,依此类推。…...
【教学类-89-01】20250127新年篇01—— 蛇年红包(WORD模版)
祈愿在2025蛇年里, 伟大的祖国风调雨顺、国泰民安、每个人齐心协力,共同经历这百年未有之大变局时代(国际政治、AI技术……) 祝福亲友同事孩子们平安健康(安全、安全、安全)、巳巳如意! 背景需…...
[权限提升] 操作系统权限介绍
关注这个专栏的其他相关笔记:[内网安全] 内网渗透 - 学习手册-CSDN博客 权限提升简称提权,顾名思义就是提升自己在目标系统中的权限。现在的操作系统都是多用户操作系统,用户之间都有权限控制,我们通过 Web 漏洞拿到的 Web 进程的…...
DeepSeek异军突起,重塑AI格局
DeepSeek异军突起,重塑AI格局这两天AI 圈发生了比过年更令人兴奋的事情,“Meta内部反水事件”、“黄仁勋的底盘问题”,以及AI格局的大动荡,一切都是因为那个叫DeepSeek的“中国自主AI”!它由幻方量化开发,以…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
