初阶数据结构(六)队列的介绍与实现

💓博主csdn个人主页:小小unicorn💓
⏩专栏分类:C++

🚚代码仓库:小小unicorn的学习足迹🚚
🌹🌹🌹关注我带你学习编程知识

  • 队列的介绍
    • 队列的概念:
    • 队列的结构:
  • 队列的实现
    • 创建队列
    • 初始化队列
    • 销毁队列
    • 队尾入队列
    • 对头出队列
    • 获取队列头部元素
    • 获取队列尾部元素
    • 检测队列是否为空
    • 获取队列中有效元素个数
  • 总结:

队列的介绍

队列的概念:

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。队列遵守先进先出FIFO(First In First Out)的原则。

入队列:队列的插入操作叫做入队列,进行插入操作的一端称为队尾。

出队列:队列的删除操作叫做出队列,进行删除操作的一端称为队头。

队列的结构:

在这里插入图片描述

队列的实现

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建队列

首先我们需要创建一个结点类型,类型包含了该结点的数据指向下一结点的指针。

typedef int QDataType;typedef struct QListNode
{struct QListNode* next;               //指针域QDataType data;                       //数据域
}QListNode;

其次队列与普通链表又有所不同,普通链表只需要知道链表的头指针,而队列的信息包括了队头和队尾,所以我们需要再创建一个结构体用于存放队列的队头和队尾。

typedef struct Queue
{QListNode* head;//队头QListNode* tail;//队尾
}Queue;

初始化队列

我们需要一个初始化函数,对刚创建的队列进行初始化

//初始化队列
void QueueInit(Queue* pq)
{assert(pq);//起始时队列为空pq->head = NULL;pq->tail = NULL;
}

销毁队列

因为队列中的每一个结点所占用的内存空间都是动态开辟的,当我们使用完队列后需要及时释放队列中的每一个结点。

//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);QListNode* cur = pq->head;//接收队头//遍历链表,逐个释放结点while (cur){QListNode* next = cur->next;free(cur);cur = next;}pq->head = NULL;//队头置空pq->tail = NULL;//队尾置空
}

队尾入队列

入队列,也就是说申请一个新结点并将其链接到队尾,然后改变队尾的指针指向

需要注意的是:若队列中原本无数据,那么我们只需让队头和队尾均指向这个新申请的结点即可。

//队尾入队列
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QListNode* newnode = (QListNode*)malloc(sizeof(QListNode));//申请新结点if (newnode == NULL){printf("malloc fail\n");exit(-1);}newnode->data = x;                                        //新结点赋值newnode->next = NULL;                                     //新结点指针域置空if (pq->head == NULL)                                     //队列中原本无结点{pq->head = pq->tail = newnode;                         //队头、队尾直接指向新结点}else                                                       //队列中原本有结点{pq->tail->next = newnode;                              //最后一个结点指向新结点pq->tail = newnode;                                    //改变队尾指针指向}
}

对头出队列

出队列,也就是释放队头指针指向的结点并改变队头指针的指向

若队列中只有一个结点,那么直接将该结点释放,然后将队头和队尾置空即可。

//队头出队列
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));                            //检测队列是否为空if (pq->head->next == NULL)                         //队列中只有一个结点{free(pq->head);pq->head = NULL;pq->tail = NULL;}else//队列中有多个结点{QListNode* next = pq->head->next;free(pq->head);pq->head = next;                                 //改变队头指针指向}
}

获取队列头部元素

获取队列头部元素,就是返回队头指针指向的数据。

//获取队列头部元素
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));                        //检测队列是否为空return pq->head->data;                          //返回队头指针指向的数据
}

获取队列尾部元素

获取队列尾部元素,也就是返回队尾指针指向的数据。

//获取队列尾部元素
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));                  //检测队列是否为空return pq->tail->data;                    //返回队尾指针指向的数据
}

检测队列是否为空

检测队列是否为空,也就是判断队头指针指向的内容是否为空。

//检测队列是否为空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}

获取队列中有效元素个数

队列中有效元素个数,也就是队列中的结点个数

我们只需遍历一下队列,统计队列中的结点数并返回即可。

//获取队列中有效元素个数
int QueueSize(Queue* pq)
{assert(pq);QListNode* cur = pq->head;                       //接收队头int count = 0;                                   //记录结点个数while (cur)                                      //遍历队列{count++;cur = cur->next;}return count;                                    //返回队列中的结点数
}

总结:

初阶数据结构(五)(六)讲的是栈和队列,它们都是特殊的线性表,只不过对插入和删除操作做了限制。

(stack)是限定仅在表尾进行插入和删除操作的线性表。

对列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线
性表。

它们均可以用线性表的顺序存储结构来实现,但都存在着顺序存储的一些弊端。因此它们各自有各自的技巧来解决这个问题。

对于栈来说,如果是两个相同数据类型的栈,则可以用数组的两端作栈底的方法来让两个栈共享数据,这就可以最大化地利用数组的空间。

对于队列来说,为了避免数组插入和删除时需要移动数据,于是就引入了循环队列,使得队头和队尾可以在数组中循环变化。解决了移动数据的时间损耗,使得本来插入和删除是O(n)的时间复杂度变成了O(1)。

它们也都可以通过链式存储结构来实现,实现原则上与线性表基本相同,如下图所示。

文章到这里就要告一段落了,有更好的思路或问题的,欢迎留言评论区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/109150.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GWO-LSTM交通流量预测(python代码)

使用 GWO 优化 LSTM 模型的参数,从而实现交通流量的预测方法 代码运行版本要求 1.项目文件夹 data是数据文件夹,data.py是数据归一化等数据预处理脚本 images文件夹装的是不同模型结构打印图 model文件夹 GWO-LSTM测试集效果 效果视频:GWO…

SNN论文总结

Is SNN a great work ? Is SNN a convolutional work ? ANN的量化在SNN中是怎么体现的,和threshold有关系吗,threshold可训练和这个有关吗(应该无关) 解决过发放不发放的问题。 Intuation SNN编码方式 Image to spike patter…

stm32之19.温湿度模块(待补充)

dth11.c文件① #include "dht11.h" #include "delay.h"// 1、温湿度模块初始化(PG9) void Dht11_Init(void) {// 0、GPIO外设信息结构体GPIO_InitTypeDef GPIO_InitStruct;// 1、使能硬件时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//…

Pyqt5开发实战记录

入职以来第一个开发项目: 1、如何给Qlabel加边框:右键label对象,选择“改变样式表”输入一下代码: border: 1px solid black;2、如何让垂直布局中button大小不发生变化:其实很简单,只需要设置button的最大…

【seaweedfs】2、Finding a needle in Haystack: Facebook’s photo storage 分布式对象存储论文

文章目录 一、介绍二、背景、设计理念2.1 背景2.2 NFS-based Design2.3 Discussion 三、设计和实现3.1 概览3.2 Haystack Directory3.3 Haystack Cache3.4 Haystack Store3.4.1 Photo Read3.4.2 Photo Write3.4.3 Photo Delete3.4.4 The Index File3.4.5 Filesystem 3.5 Recove…

WebGL 缓冲区对象介绍,创建并使用缓冲区,使用缓冲区对象向顶点着色器传入多个顶点数据的所有步骤

目录 使用缓冲区对象 使用缓冲区对象向顶点着色器传入多个顶点的数据,需要遵循以下五个步骤。 创建缓冲区对象(gl.createBuffer()) gl.createBuffer()的函数规范 gl.deleteBuffer &#…

C# winform加载yolov8模型测试(附例程)

第一步:在NuGet中下载Yolov8.Net 第二步:引用 using Yolov8Net; 第三步:加载模型 private IPredictor yolov8 YoloV8Predictor.Create("D:\\0MyWork\\Learn\\vs2022\\yolov_onnx\\best.onnx", mylabel); 第四步:图…

【OpenCV • c++】图像对比度调整 | 图像亮度调整

🚀 个人简介:CSDN「博客新星」TOP 10 , C/C 领域新星创作者💟 作 者:锡兰_CC ❣️📝 专 栏:【OpenCV • c】计算机视觉🌈 若有帮助,还请关注➕点赞➕收藏&#xff…

window系统中如何判断是物理机还是虚拟机及VMPROTECT无法检测云主机

为什么要判断物理机,因为授权不能对虚拟机安装后的软件进行授权。虚拟机可以复制可以克隆,无法作为一个不可复制ID来使用。 总结了如何判断物理机: 1. 用systeminfo的系统型号。(注,有资料是看处理器和bios。但是我这…

一步一步实验,讲解python中模块和包的使用

背景 为什么要提出这个问题? 在一个项目中,每一个python文件打开后,都会看到依赖了其他的一些包、模块等;概念混乱,魔改目标不清晰 为什么要修改? 如果需要将某开源包进行自定义处理,不再使…

Python 包管理(pip、conda)基本使用指南

Python 包管理 概述 介绍 Python 有丰富的开源的第三方库和包,可以帮助完成各种任务,扩展 Python 的功能,例如 NumPy 用于科学计算,Pandas 用于数据处理,Matplotlib 用于绘图等。在开始编写 Pytlhon 程序之前&#…

数据隐私与安全在大数据时代的挑战与应对

文章目录 数据隐私的挑战数据安全的挑战应对策略和方法1. 合规和监管2. 加密技术3. 匿名化和脱敏4. 安全意识培训5. 隐私保护技术 结论 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏&…

【算法与数据结构】513、LeetCode找树左下角的值

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:这道题用层序遍历来做比较简单,最底层最左边节点就是层序遍历当中最底层元素容器的第一个值…

vue 简单实验 自定义组件 独立模块

1.概要 2.代码 2.1 const Counter {data() {return {counter: 0}},template:<div>Counter: {{ counter }}</div> }export default Counter 2.2 import Counter from ./t2.jsconst app Vue.createApp({components: {component-a: Counter} })app.mount(#count…

浅析 GlusterFS 与 JuiceFS 的架构异同

在进行分布式文件存储解决方案的选型时&#xff0c;GlusterFS 无疑是一个不可忽视的考虑对象。作为一款开源的软件定义分布式存储解决方案&#xff0c;GlusterFS 能够在单个集群中支持高达 PiB 级别的数据存储。自从首次发布以来&#xff0c;已经有超过十年的发展历程。目前&am…

不使用ip和port如何进行网络通讯(raw socket应用例子)

主要应用方向是上位机和嵌软(如stm32单片机)通讯&#xff0c;不在单片机中嵌入web server&#xff0c;即mac层通讯。 一、下面先了解网络数据包组成。 常见数据包的包头长度: EtherHeader Length: 14 BytesTCP Header Length : 20 BytesUDP Header Length : 8 BytesIP Heade…

Spring@Scheduled定时任务接入XXL-JOB的一种方案(基于SC Gateway)

背景 目前在职的公司&#xff0c;维护着Spring Cloud分布式微服务项目有25个。其中有10个左右微服务都写有定时任务逻辑&#xff0c;采用Spring Scheduled这种方式。 Spring Scheduled定时任务的缺点&#xff1a; 不支持集群&#xff1a;为避免重复执行&#xff0c;需引入分…

【VMware】CentOS 设置静态IP(Windows 宿主机)

文章目录 1. 更改网络适配器设置2. 配置虚拟网络编辑器3. 修改 CentOS 网络配置文件4. ping 测试结果 宿主机&#xff1a;Win11 22H2 虚拟机&#xff1a;CentOS-Stream-9-20230612.0 (Minimal) 1. 更改网络适配器设置 Win R&#xff1a;control 打开控制面板 依次点击&#x…

【应用层】网络基础 -- HTTPS协议

HTTPS 协议原理加密为什么要加密常见的加密方式对称加密非对称加密 数据摘要&&数据指纹 HTTPS 的工作过程探究方案1-只使用对称加密方案2-只使用非对称加密方案3-双方都使用非对称加密方案4-非对称加密对称加密中间人攻击-针对上面的场景 CA认证理解数据签名方案5-非对…

15-模型 - 一对多 多对多

一对多&#xff1a; 1. 在多的表里定义外键 db.ForeignKey(主键) 2. 增加字段 db.relationship 建立联系 ("关联表类名","反向引用名") from ext import db# 一 class User(db.Model):id db.Column(db.Integer, primary_keyTrue, autoincrementTrue)us…