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

【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】队列-设计循环队列

一、题目 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普…...

设置jmeter界面图标字体大小

设置jmeter界面图标字体大小 方法&#xff1a;点击“选项” -> 点击放大、缩小。&#xff08;可进行全局的菜单、左侧目录结构树、元件界面显示等字体图标的放大、缩小。&#xff09;...

Xposed-Hook

配置 Xposed 模块的 AndroidManifest.xml&#xff1a; <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"your.package.name"><applicationandr…...

设计模式Python版 原型模式

文章目录 前言一、原型模式二、原型模式示例三、原型管理器 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对…...

QT:图像上绘制图形

需求描述 1、展示一张图像 2、在图像上可以使用数据绘制图像&#xff1a;矩形、不规则图形、线条 3、有按键可以选择 概要设计 规划布局如下 1、左边是Qlabel 用于展示图片 2、右边是三个按钮 具体实现 1、 首先设计 UI 界面&#xff0c;对控件进行布局 在 mainwindow.u…...

GPU上没程序在跑但是显存被占用

原因&#xff1a;存在僵尸线程&#xff0c;运行完但是没有释放内存 查看僵尸线程 fuser -v /dev/nvidia*关闭僵尸线程 pkill -9 -u 用户名 程序名 举例&#xff1a;pkill -9 -u grs python参考&#xff1a;https://blog.csdn.net/qq_40206371/article/details/143798866...

wordpress代码结构解析

WordPress 是一个基于 PHP 和 MySQL 的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;广泛用于构建网站和博客。要解析 WordPress 代码&#xff0c;首先需要了解其核心结构、主要文件和常用的函数。以下是 WordPress 代码解析的基本指南&#xff1a; --- ### 1. *…...

【Unity3D】实现2D小地图效果

目录 一、玩家脚本Player 二、Canvas组件设置 三、小地图相关 四、GameLogicMap脚本修改 基于&#xff1a;【Unity3D】Tilemap俯视角像素游戏案例-CSDN博客 2D玩家添加Dotween移动DOPath效果&#xff0c;移动完成后进行刷新小地图&#xff08;小地图会顺便刷新大地图&…...

关联传播和 Python 和 Scikit-learn 实现

文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数&#xff1a;集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…...

https数字签名手动验签

以bing.com 为例 1. CA 层级的基本概念 CA 层级是一种树状结构&#xff0c;由多个层级的 CA 组成。每个 CA 负责为其下一层级的实体&#xff08;如子 CA 或终端实体&#xff09;颁发证书。层级结构的顶端是 根 CA&#xff08;Root CA&#xff09;&#xff0c;它是整个 PKI 体…...

LeetCode:62.不同路径

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &…...

如果我想设计一款复古风格的壁纸,应该选什么颜色?

设计复古风格的壁纸时&#xff0c;选择合适的颜色是营造怀旧和经典氛围的关键。复古风格通常使用一些温暖、柔和且带有岁月痕迹的色调。以下是一些适合复古风格壁纸的颜色选择和搭配建议&#xff1a; 一、复古风格的主色调 棕色系&#xff1a; 特点&#xff1a;棕色是复古风格的…...

【数据结构】树的基本:结点、度、高度与计算

树是数据结构中一种重要的非线性结构&#xff0c;广泛应用于计算机科学的各个领域&#xff0c;例如文件系统、数据库索引、编译器等。理解树的各种性质&#xff0c;如结点数、度、高度等&#xff0c;对于解决实际问题至关重要。 本文将会探讨树的基本概念&#xff0c;以及给出几…...

【Pytest】生成html报告中,中文乱码问题解决方案

链接上一篇文章:https://blog.csdn.net/u013080870/article/details/145369926?spm1001.2014.3001.5502 中文乱码问题&#xff0c;python3&#xff0c;Python3.7后&#xff0c;还一个文件就是result.py 因为中文可以在内容中&#xff0c;也可能在文件名&#xff0c;类名&…...

week08_文本匹配任务

1、文本匹配任务概述 狭义&#xff1a; 给定一组文本&#xff0c;判断其是否语义相似 今天天气不错 match 今儿个天不错呀 √ 今天天气不错 match 你的代码有bug 以分值形式给出相似度 今天天气不错 match 今儿个天不错呀 0.9 今天天气不错 match…...

JUC--ConcurrentHashMap底层原理

ConcurrentHashMap底层原理 ConcurrentHashMapJDK1.7底层结构线程安全底层具体实现 JDK1.8底层结构线程安全底层具体实现 总结JDK 1.7 和 JDK 1.8实现有什么不同&#xff1f;ConcurrentHashMap 中的 CAS 应用 ConcurrentHashMap ConcurrentHashMap 是一种线程安全的高效Map集合…...

【2024年华为OD机试】(C卷,200分)- 推荐多样性 (JavaScriptJava PythonC/C++)

一、问题描述 问题描述 我们需要从多个已排序的列表中选取元素,以填充多个窗口。每个窗口需要展示一定数量的元素,且元素的选择需要遵循特定的穿插策略。具体来说,我们需要: 从第一个列表中为每个窗口选择一个元素,然后从第二个列表中为每个窗口选择一个元素,依此类推。…...

【教学类-89-01】20250127新年篇01—— 蛇年红包(WORD模版)

祈愿在2025蛇年里&#xff0c; 伟大的祖国风调雨顺、国泰民安、每个人齐心协力&#xff0c;共同经历这百年未有之大变局时代&#xff08;国际政治、AI技术……&#xff09; 祝福亲友同事孩子们平安健康&#xff08;安全、安全、安全&#xff09;、巳巳如意&#xff01; 背景需…...

[权限提升] 操作系统权限介绍

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 权限提升简称提权&#xff0c;顾名思义就是提升自己在目标系统中的权限。现在的操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;我们通过 Web 漏洞拿到的 Web 进程的…...

DeepSeek异军突起,重塑AI格局

DeepSeek异军突起&#xff0c;重塑AI格局这两天AI 圈发生了比过年更令人兴奋的事情&#xff0c;“Meta内部反水事件”、“黄仁勋的底盘问题”&#xff0c;以及AI格局的大动荡&#xff0c;一切都是因为那个叫DeepSeek的“中国自主AI”&#xff01;它由幻方量化开发&#xff0c;以…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...