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

【数据结构】详解队列

现在我们来掌握一下队列!如果有对往期知识有不足地方,可翻阅之前文章哦!

个人主页:小八哥向前冲~-CSDN博客

所属专栏:数据结构【c语言版】_小八哥向前冲~的博客-CSDN博客

栈和队列的实现其实都是对你顺序表和链表的检验,只有一些新的概念罢了!

哈哈!不信就往下看吧!!!

目录

什么是队列?

扩展--循环队列

队列的实现

初始化

队列的插入

队列的判空

队列的删除

队列的尾数据

队列的头数据

队列的销毁

总代码

Queue.h文件

Queue.c文件


什么是队列?

  • 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)
  • 入队列:进行插入操作的一端称为队尾。
  • 出队列:进行删除操作的一端称为队头。

上图理解:

注意:遵循先进先出的原则!这个原则就是区分栈(后进先出)和队列(先进先出)方法!

我们来看看一个队列需要有的最基本要求:详情见--queue - C++ Reference

了解了队列的基本概念,我们来扩展一下!

扩展--循环队列

生活中队列很常用,而在实际的生活中,有时我们会用到循环队列。

循环队列它也有一些应用场景。如:在操作系统中的生产者消费者模型(这个我们后续提到!)

在这种问题中,环形队列可以使用数组实现,也可以使用循环链表实现

我们图上了解:

空的环形队列

满的环形队列:

注意:为了能区别Q.front=Q.rear为队满还是队空,我们通常认为Q.rear+1=Q.front为满!

ok!了解了队列的基本,我们来巩固一下:

3.循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作 后, front=rear=99 ,则循环队列中的元素个数为( )

A .1

B.2

C.99

D.0或者100

4.以下( )不是队列的基本运算?

A.从队尾插入一个新元素

B.从队列中删除第i个元素

C.判断一个队列是否为空

D.读取队头元素的值

5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为( )?(假设 队头不存放数据)

A.(rear - front + N) % N + 1

B.(rear - front + N) % N

C.ear - front) % (N + 1)

D.(rear - front + N) % (N - 1)

答案:3.D  4.B   5.B

参考:

3.我们肯定知道元素个数为空时,front=rear,可当front=rear时,也有元素为满的情况!

5.因为是循环队列,单纯尾指针和头指针相减并不能求出总长。

现在我们来实现一下队列(按照一个队列的基本要求)。

当然,队列像栈一样,都可以写成链表和顺序表的底层!这里主要了解链表!

队列的实现

还是老样子:我们创建Queue.h文件声明各种变量和函数,创建Queue.c文件来将函数实现。

思路:

 我们在实现一个函数时,要先弄清楚参数。

既然底层是链表,那么就得定义节点

typedef int QDataType;
//队列节点
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;

我们来看看我们的底层逻辑:需要头指针记录头,尾指针记录尾,一个计数变量

既然需要这几个变量时刻记录,不如我们直接定义一个结构体来管理这些参数。

作用:

这里将参数管理起来可以避免插入和删除函数参数二级指针的使用!(下面会有体现)

typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;

ok! 我们来将这些函数一一实现。

初始化

我们得先将记录的参数初始化一下,以便后续参数的更新!

//队列的初始化
void QInit(Queue* p)
{assert(p);p->phead = p->ptail = NULL;p->size = 0;
}

队列的插入

这里谨记:队列是先进先出,栈是后进先出,不要搞混了!

这里由于记录好了尾指针,我们直接在尾后面插入就行!这样看是不是觉得很方便?避免了二级指针的使用。

在插入之前,需要开辟一个节点,然后开始插入!

//队列的插入
void Qpush(Queue* p, QDataType x)
{assert(p);QNode* node = (QNode*)malloc(sizeof(QNode));if (node == NULL){perror("malloc failed!");return;}//初始化节点node->next = NULL;node->val = x;//开始插入if (p->phead == NULL){p->phead = p->ptail = node;}else{p->ptail->next = node;p->ptail = node;}
}

队列的判空

我们只需要在管理的数据变量中判断计数器的值是否为空就行!这也侧面体现了我们用一个结构体管理变量的好处!

//队列的判空
bool QEmpty(Queue* p)
{assert(p);return p->size==0;
}

队列的删除

  • 在删除之前,我们要先判断队列是否为空,如果为空的话,不能删除。
  • 因为队列是先进先出原则,既然尾部进数据,那么头部出数据。所以我们删除数据要在头部删除!

而在删除时要讨论队列中一个节点还是多个节点问题。本来不讨论我们也能删除数据,那么是为什么要讨论呢?

当队列中只有一个节点时,头指针等于尾指针一起指向这一个节点,当删除时,头指针移向空,然后将这个节点释放掉,但尾指针仍然指向那个节点,当我们访问尾指针指向的那个值时,程序出现错误!

我们上图理解:

于是我们能这样写代码:

//队列的删除
void Qpop(Queue* p)
{assert(p);//删除之前不能为空assert(!QEmpty(p));//讨论队列只有一个节点的情况!if (p->phead->next == NULL){free(p->phead);p->phead = p->ptail = NULL;}else{QNode* next = p->phead->next;free(p->phead);p->phead = next;}p->size--;
}

队列的尾数据

有了前面的基础,我们访问队列尾数据十分简单,但需要注意的是,判断队列是否为空。

//队列的尾数据
QDataType QBack(Queue* p)
{assert(p);assert(!QEmpty(p));return p->ptail->val;
}

队列的头数据

能十分访问尾数据,访问头数据也是如此,但是别忘了要判断队列是否为空。

//队列的头数据
QDataType QFront(Queue* p)
{assert(p);assert(!QEmpty(p));return p->phead->val;
}

队列的销毁

我们动态开辟了内存节点,那么当我们不用了这个队列时,不要忘了销毁它!

//队列的销毁
void QDestroy(Queue* p)
{assert(p);QNode* cur = p->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}
}

总代码

Queue.h文件

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>typedef int QDataType;
//队列节点
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;//队列相关变量
//先进先出
typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;//队列的初始化
void QInit(Queue* p);
//队列的插入
void Qpush(Queue* p, QDataType x);
//队列的判空
bool QEmpty(Queue* p);
//队列的删除
void Qpop(Queue* p);
//队列的尾数据
QDataType QBack(Queue* p);
//队列的头数据
QDataType QFront(Queue* p);
//队列的销毁
void QDestroy(Queue* p);

Queue.c文件

#include"Queue.h"
//队列的初始化
void QInit(Queue* p)
{assert(p);p->phead = p->ptail = NULL;p->size = 0;
}
//队列的插入
void Qpush(Queue* p, QDataType x)
{assert(p);QNode* node = (QNode*)malloc(sizeof(QNode));if (node == NULL){perror("malloc failed!");return;}//初始化节点node->next = NULL;node->val = x;//开始插入if (p->phead == NULL){p->phead = p->ptail = node;}else{p->ptail->next = node;p->ptail = node;}
}
//队列的判空
bool QEmpty(Queue* p)
{assert(p);return p->phead == NULL;
}
//队列的删除
void Qpop(Queue* p)
{assert(p);//删除之前不能为空assert(!QEmpty(p));//讨论队列只有一个节点的情况!if (p->phead->next == NULL){free(p->phead);p->phead = p->ptail = NULL;}else{QNode* next = p->phead->next;free(p->phead);p->phead = next;}p->size--;
}
//队列的尾数据
QDataType QBack(Queue* p)
{assert(p);assert(!QEmpty(p));return p->ptail->val;
}
//队列的头数据
QDataType QFront(Queue* p)
{assert(p);assert(!QEmpty(p));return p->phead->val;
}
//队列的销毁
void QDestroy(Queue* p)
{assert(p);QNode* cur = p->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}
}

好了,现在你已经掌握了队列,快去题海感受一下吧!

我们下期见!

相关文章:

【数据结构】详解队列

现在我们来掌握一下队列&#xff01;如果有对往期知识有不足地方&#xff0c;可翻阅之前文章哦&#xff01; 个人主页&#xff1a;小八哥向前冲~-CSDN博客 所属专栏&#xff1a;数据结构【c语言版】_小八哥向前冲~的博客-CSDN博客 栈和队列的实现其实都是对你顺序表和链表的检验…...

大模型微调方法汇总

微调方法 Freeze方法P-tuning方法 prefix-tuningPrompt TuningP-tuning v1P-tuning v2Lora方法 重要相关参数LoRA 的优势Qlora方法 相关参数微调经验 模型选择模型大小选择数据处理微调方案英文模型需要做词表扩充吗&#xff1f;如何避免灾难遗忘大模型的幻觉问题微调后的输出…...

探究NVMe SSD HMB应用场景与影响-<续>

如果需要采用HMB功能&#xff0c;需要SSD支持NVME协议且NVMe 1.2及以上版本。NVME协议中对HMB对应有2个关键参数&#xff1a; HMB建议值&#xff08;HMPRE&#xff09;&#xff1a;设定实际分配给HMB使用的主机内存容量&#xff0c;为设备提供最优性能的内存分配量。 HMB最小值…...

YTU 3166 共享单车 DFS 记忆化搜索

问题 D: 共享单车 题目描述 共享单车走进烟台&#xff0c;小明决定尝试。小明启动共享单车 App&#xff0c;轻松地找到附近的单车。那么问题来了&#xff0c;到最近的那辆单车&#xff0c;小明大约要走多少米呢&#xff1f; 现在简化问题。将地图设定成一个由 100100 米的像…...

RAG应用中的路由模式

依据的用户查询意图在 RAG 应用程序使用“路由控制模式”可以帮助我们创建更强大的 RAG 应用程序。我们通常希望用户能够访问的数据可以来自各种来源,如报告、文档、图片、数据库和第三方系统。 对于基于业务的 RAG 应用程序,我们可能还希望用户能够与其它业务系统进行交互,…...

运维:SSH常用命令简介

SH&#xff0c;全称为Secure Shell&#xff0c;是建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠&#xff0c;专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。通过 SSH 可以对所有传输的数据进行加密&…...

Springboot+Vue项目-基于Java+MySQL的流浪动物管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…...

力扣刷题:四数相加Ⅱ

题目详情&#xff1a; 解法一&#xff1a;暴力枚举 对于这道题&#xff0c;我们的第一思路就是暴力枚举&#xff0c;我们可以写一个四层的for循环进行暴力匹配&#xff0c;只要相加的结果等于0就进行统计。但是我们会发现&#xff0c;我们的事件复杂度为O(N^4)事件复杂度非常大…...

如果通过Glide 设置图片圆角

要给图片设置一个圆角,通常方法是在ImageView 标签外添加一个CardView 标签,然后设置圆角值,但是今天遇到一个问题就是 RecyclerView Item 中这样操作的话会遇到这样的一个报错: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.rec…...

Chatgpt学习技巧

论文润色指令 论文润色常用指令 通用话术&#xff1a; Below is a paragraph from an academic paper. Polish the writing to meet the academic style, improve the spelling, grammar, clarity, concision and overall readability. When necessary, rewrite the whole se…...

[初学rust] 06_rust 元组

rust 元组 表现形式 和python的元组类似&#xff0c;rust中的元组是一个有序列表&#xff0c;可以包含多种不同类型的数据。 let tup (500, 6.4, a);模式匹配解构元组 和python中的解构一样&#xff0c;rust也支持模式匹配解构元组&#xff0c;但是需要注意的是&#xff0…...

基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (四)

基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;四&#xff09; 大家继续看 https://lilianweng.github.io/posts/2023-06-23-agent/的文档内容 第三部分&#xff1a;工具使用 工具的使用是人类的一个显着而显着的特征。我们创造、修改和利用外部物体来完成超…...

C++进阶:哈希(1)

目录 1. 简介unordered_set与unordered_map2. 哈希表&#xff08;散列&#xff09;2.1 哈希表的引入2.2 闭散列的除留余数法2.2.1 前置知识补充与描述2.2.2 闭散列哈希表实现 2.3 开散列的哈希桶2.3.1 结构描述2.3.2 开散列哈希桶实现2.3.3 哈希桶的迭代器与key值处理仿函数 3.…...

第三节课,功能2:开发后端用户的管理接口-- postman--debug测试

一、如何使用postman 网址&#xff1a; https://www.postman.com/downloads/ 【Postman小白教程】五分钟学会如何使用Postman~_哔哩哔哩_bilibili postman安装使用_bowser agent在postman哪里-CSDN博客 二、下载后 登录&#xff0c;开始测试 2.1 关于postman 报错&#…...

Docker-compsoe部署prysm-beacon-chain + geth服务(geth版本v1.14.0)

1、创建目录结构 ~ # mkdir -p /data/docker-compose/eth ~ # cd /data/docker-compose/eth /data/docker-compose/eth# mkdir beacondata eth ethdata prysm2、编写prysm-beacon-chain Dockerfile和启动脚本文件 /data/docker-compose/eth# vim Dockerfile /data/docker-…...

前端人员如何理解进程和线程

进程和线程的概念&#xff1a; 进程和线程本质都是cpu工作过程的时间片。 进程可以理解为cpu在运行指令即加载保存上下文所要用的时间。也可以理解为一个应用程序运行的实例。 线程是进程中更小的单位&#xff0c;描述一段指令所需要的时间。 进程是资源分配的最小单位&#xf…...

Linux下网络命令

目录 需求1-查看本机是否存在22端口解法1解法2解法3 需求2-查看其他主机是否存在22端口解法1解法2解法3 需求3-查看TCP连接解法1/2 需求4-统计80端口tcp连接次数解法 需求5-查看总体网络速度解法 需求6-查看进程流量解法 需求7-dns解法 需求8-traceroute到baidu解法 需求9-查看…...

Php swoole和mqtt

在 PHP 中使用 Swoole 处理 MQTT 订阅消息是一种高效的方式&#xff0c;可以充分利用 Swoole 协程的非阻塞特性和高性能 I/O 处理能力。下面是一个示例代码&#xff0c;演示了如何使用 Swoole 的 MQTT 客户端来订阅消息&#xff0c;并加以详细说明。 1. 安装 Swoole 首先&…...

Spring STOMP-连接到消息代理

STOMP 代理中继维护一个与消息代理的“系统”TCP 连接。这个连接仅用于来自服务器端应用程序的消息&#xff0c;不用于接收消息。您可以为此连接配置STOMP凭据&#xff08;即STOMP帧的login和passcode头部&#xff09;。这在XML命名空间和Java配置中都以systemLogin和systemPas…...

Excel中的`MMULT`函数

Excel中的MMULT函数是一个用于执行矩阵乘法运算的函数。矩阵乘法是线性代数中的一个基本运算&#xff0c;它允许我们计算两个矩阵的乘积&#xff0c;得到一个新的矩阵。与普通的标量乘法不同&#xff0c;矩阵乘法涉及到行与列的对应元素相乘然后求和的过程。MMULT函数在进行数据…...

Deepfake Offensive Toolkit Docker部署:跨平台解决方案详解

Deepfake Offensive Toolkit Docker部署&#xff1a;跨平台解决方案详解 【免费下载链接】dot The Deepfake Offensive Toolkit 项目地址: https://gitcode.com/gh_mirrors/dot/dot Deepfake Offensive Toolkit&#xff08;简称dot&#xff09;是一款功能强大的深度学习…...

如何突破Windows权限壁垒?系统管理专家的秘密武器

如何突破Windows权限壁垒&#xff1f;系统管理专家的秘密武器 【免费下载链接】NSudo [Deprecated, work in progress alternative: https://github.com/M2Team/NanaRun] Series of System Administration Tools 项目地址: https://gitcode.com/gh_mirrors/ns/NSudo 在W…...

双屏天花板用法!YogaBook 9i 多屏操作全演示

YogaBook 9i 作为双屏笔记本里的标志性机型&#xff0c;凭借两块高素质触控屏带来了完全不同于传统电脑的使用体验&#xff0c;但不少用户拿到手只当普通笔记本使用&#xff0c;没能发挥双屏协同的真正效率&#xff0c;多屏联动、分屏操作、跨屏交互这些核心亮点都被白白浪费。…...

SDMatte抠图实战教程:玻璃/薄纱/羽毛一键去背景,保姆级Web部署指南

SDMatte抠图实战教程&#xff1a;玻璃/薄纱/羽毛一键去背景&#xff0c;保姆级Web部署指南 1. 为什么选择SDMatte进行专业抠图 在日常设计工作中&#xff0c;抠图是最基础也最耗时的环节之一。特别是遇到玻璃制品、薄纱材质、羽毛边缘这类复杂对象时&#xff0c;传统Photosho…...

GLM-OCR模型安装包制作:将模型与服务打包成可执行文件

GLM-OCR模型安装包制作&#xff1a;将模型与服务打包成可执行文件 你是不是也遇到过这样的情况&#xff1f;自己好不容易把一个AI模型跑起来了&#xff0c;效果也不错&#xff0c;想分享给同事或者朋友用用&#xff0c;结果对方光是配环境、装依赖就折腾了半天&#xff0c;最后…...

Verilog实战精要:从语法基础到高效状态机设计

1. Verilog语法基础&#xff1a;从硬件思维出发 第一次接触Verilog时&#xff0c;很多人会把它当成普通编程语言来学&#xff0c;结果发现处处碰壁。我当年在FPGA项目上栽的第一个跟头&#xff0c;就是把阻塞赋值用在了时钟触发的always块里&#xff0c;导致仿真结果和实际硬件…...

基于python视频弹幕情感分析 视频可视化 短视频推荐系统 协同过滤推荐算法

1、项目介绍 技术栈&#xff1a; Python语言、Flask框架、 requests爬虫、协同过滤推荐算法、sqlite数据库、bilibili数据、前台后台 B站数据采集分析、推荐与可视化分析系统是一个强大的工具&#xff0c;它利用Python语言、Flask框架、requests爬虫技术、协同过滤推荐算法以及…...

MATLAB 数值计算辅助:分析 Stable Yogi 生成图像的色彩与纹理特征

MATLAB 数值计算辅助&#xff1a;分析 Stable Yogi 生成图像的色彩与纹理特征 1. 引言 最近在尝试用 Stable Yogi 生成一些皮革纹理的设计图&#xff0c;效果确实挺惊艳的。但生成得多了&#xff0c;就遇到一个新问题&#xff1a;我手头攒了几百张图&#xff0c;风格各异&…...

EDK II代码格式化集成指南:IDE集成步骤详解

EDK II代码格式化集成指南&#xff1a;IDE集成步骤详解 【免费下载链接】edk2 EDK II 项目地址: https://gitcode.com/gh_mirrors/ed/edk2 EDK II作为现代UEFI固件开发的核心框架&#xff0c;其代码质量直接影响到固件的稳定性和安全性。本文将详细介绍如何将EDK II代码…...

LFM2.5-1.2B-Thinking-GGUF开源可部署:自主可控轻量模型替代方案深度评测

LFM2.5-1.2B-Thinking-GGUF开源可部署&#xff1a;自主可控轻量模型替代方案深度评测 1. 模型概述 LFM2.5-1.2B-Thinking-GGUF是Liquid AI推出的轻量级文本生成模型&#xff0c;专为低资源环境优化设计。该模型采用GGUF格式存储&#xff0c;配合llama.cpp运行时&#xff0c;能…...