数据结构——队列的基本操作

前言

介绍

 🍃数据结构专区:数据结构

参考

该部分知识参考于《数据结构(C语言版 第2版)》24~28页

🌈每一个清晨,都是世界对你说的最温柔的早安:ૢ(≧▽≦)و✨


目录

前言

1、队列的基本概念

2、基于数组的队列

2.1  宏定义

2.2  数组队列的结构体定义

2.3  队列的初始化

2.4  销毁队列

2.5  求队列长度

2.6  入队

2.7  出队

2.8  获取队头元素

2.9  遍历打印

2.10  整体代码(含测试)

3、基于链表的队列

3.1  宏定义

3.2  链表队列的结构体定义

3.3  队列的初始化

3.4  销毁队列

3.5  求队列中元素个数

3.6  入队

3.7  出队

3.8  获取队头元素

3.9  输出队列元素

3.10  整体代码(含测试)

结语


1、队列的基本概念

队列(Queue)是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。这种操作原则使得队列具有先进先出(FIFO, First In First Out)的特性。

  • 基于数组的队列:在这种实现中,队列被限制在一个固定大小的数组中。需要维护两个指针,一个指向队首(front),另一个指向队尾(rear)。当进行入队操作时,如果rear指针指向数组的最后一个位置,且队列未满,可能需要将队列中的元素整体向前移动(或称为“循环”数组),以为新元素腾出空间。
  • 基于链表的队列:在这种实现中,队列由节点组成的链表来表示。每个节点包含数据部分和指向下一个节点的指针。队首和队尾分别由两个指针(head和tail)来维护。这种实现方式更加灵活,因为它不需要预先分配固定大小的存储空间,并且可以在常数时间内完成入队和出队操作。

2、基于数组的队列

2.1  宏定义

#include<iostream>
using namespace std;//初始化定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//Status是函数返回值类型,其值是函数结果状态代码
typedef int Status;

2.2  数组队列的结构体定义

#define MAXQSIZE 100  //队列可能达到的最大长度
typedef int QElemType;
typedef struct
{QElemType* base;  //存储空间的基地址int front;        //头指针int rear;         //尾指针
}SqQueue;//队空的条件:Q.front == Q.rear
//队满的条件:(Q.rear + 1) % MAXQSIZE == Q.front

2.3  队列的初始化

//队列初始化
Status InitQueue(SqQueue& Q)
{//构造一个空队列QQ.base = new QElemType[MAXQSIZE];  //为队列分配一个最大容量为MAXQSIZE的数组空间//Q.base = (int*)malloc(MAXQSIZE * sizeof(int));if (!Q.base)exit(OVERFLOW);      //如果开辟失败就退出程序Q.front = Q.rear = 0;    //头尾指针指向0,表示队列为空return OK;
}

2.4  销毁队列

// 销毁队列
Status DestroyQueue(SqQueue& Q)
{if (Q.base) {delete[] Q.base;Q.base = NULL;Q.front = Q.rear = 0;}return OK;
}

2.5  求队列长度

//求队列长度
int QueueLength(SqQueue Q)
{//返回队列元素个数return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

2.6  入队

//入队
Status EnQueue(SqQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素if ((Q.rear + 1) % MAXQSIZE == Q.front)return ERROR;    //若尾指针在循环意义上加1后等于头指针,表明队满Q.base[Q.rear] = e;     //新元素插入队尾Q.rear = (Q.rear + 1) % MAXQSIZE;     //队尾指针加1return OK;
}

2.7  出队

//出队
Status DeQueue(SqQueue& Q, QElemType& e)
{//删除队头元素,用e返回其值if (Q.front == Q.rear)return ERROR;  //队空e = Q.base[Q.front];Q.front = (Q.front + 1) % MAXQSIZE;return OK;
}

2.8  获取队头元素

//取队头元素
QElemType GetHead(SqQueue Q)
{//返回队头元素,不改变头指针if (Q.front != Q.rear)  //队列非空return Q.base[Q.front];
}

2.9  遍历打印

//输出队列元素
void PrintQueue(SqQueue& Q)
{printf("(front) ");int i;for (i = Q.front; i != Q.rear; i++){printf("%d ", Q.base[i]);}printf("(rear)\n");
}

2.10  整体代码(含测试)

#include<iostream>
using namespace std;//初始化定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//Status是函数返回值类型,其值是函数结果状态代码
typedef int Status;#define MAXQSIZE 100  //队列可能达到的最大长度
typedef int QElemType;
typedef struct
{QElemType* base;  //存储空间的基地址int front;        //头指针int rear;         //尾指针
}SqQueue;//队空的条件:Q.front == Q.rear
//队满的条件:(Q.rear + 1) % MAXQSIZE == Q.front//队列初始化
Status InitQueue(SqQueue& Q)
{//构造一个空队列QQ.base = new QElemType[MAXQSIZE];  //为队列分配一个最大容量为MAXQSIZE的数组空间//Q.base = (int*)malloc(MAXQSIZE * sizeof(int));if (!Q.base)exit(OVERFLOW);      //如果开辟失败就退出程序Q.front = Q.rear = 0;    //头尾指针指向0,表示队列为空return OK;
}// 销毁队列
Status DestroyQueue(SqQueue& Q)
{if (Q.base) {delete[] Q.base;Q.base = NULL;Q.front = Q.rear = 0;}return OK;
}//求队列长度
int QueueLength(SqQueue Q)
{//返回队列元素个数return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}//入队
Status EnQueue(SqQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素if ((Q.rear + 1) % MAXQSIZE == Q.front)return ERROR;    //若尾指针在循环意义上加1后等于头指针,表明队满Q.base[Q.rear] = e;     //新元素插入队尾Q.rear = (Q.rear + 1) % MAXQSIZE;     //队尾指针加1return OK;
}//出队
Status DeQueue(SqQueue& Q, QElemType& e)
{//删除队头元素,用e返回其值if (Q.front == Q.rear)return ERROR;  //队空e = Q.base[Q.front];Q.front = (Q.front + 1) % MAXQSIZE;return OK;
}//取队头元素
QElemType GetHead(SqQueue Q)
{//返回队头元素,不改变头指针if (Q.front != Q.rear)  //队列非空return Q.base[Q.front];
}//输出队列元素
void PrintQueue(SqQueue& Q)
{printf("(front) ");int i;for (i = Q.front; i != Q.rear; i++){printf("%d ", Q.base[i]);}printf("(rear)\n");
}int main()
{SqQueue Q;QElemType e;cout << "初始化队列..." << endl;if (InitQueue(Q) == OK)cout << "队列初始化成功!" << endl;elsecout << "队列初始化失败!" << endl;cout << "\n测试入队操作:" << endl;for (int i = 1; i <= 5; i++){if (EnQueue(Q, i) == OK)cout << i << " 入队成功" << endl;elsecout << i << " 入队失败" << endl;}cout << "\n当前队列:" << endl;PrintQueue(Q);cout << "\n队列长度:" << QueueLength(Q) << endl;cout << "\n测试出队操作:" << endl;for (int i = 0; i < 3; i++){if (DeQueue(Q, e) == OK)cout << e << " 出队成功" << endl;elsecout << "出队失败,队列可能为空" << endl;}cout << "\n当前队列:" << endl;PrintQueue(Q);cout << "\n队列长度:" << QueueLength(Q) << endl;cout << "\n队头元素:" << GetHead(Q) << endl;cout << "\n销毁队列..." << endl;if (DestroyQueue(Q) == OK)cout << "队列销毁成功!" << endl;elsecout << "队列销毁失败!" << endl;return 0;
}

3、基于链表的队列

3.1  宏定义

//链队列的实现
#include<iostream>
using namespace std;//初始化定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//Status是函数返回值类型,其值是函数结果状态代码
typedef int Status;

3.2  链表队列的结构体定义

typedef int QElemType;
typedef struct QNode
{QElemType data;struct QNode* next;
}QNode, *QueuePtr;typedef struct
{QueuePtr front;   //队头指针QueuePtr rear;    //队尾指针
}LinkQueue;

3.3  队列的初始化

//队列初始化
Status InitQueue(LinkQueue& Q)
{//构造一个空队列Q.front = Q.rear = new QNode;  //生成新结点作为头结点,队头和队尾指针指向此结点Q.front->next = NULL;   //头结点的指针域置空return OK;
}

3.4  销毁队列

//销毁队列
Status DestroyQueue(LinkQueue& Q)
{while (Q.front){Q.rear = Q.front->next;delete Q.front;Q.front = Q.rear;}return OK;
}

3.5  求队列中元素个数

//求队列中元素数量
int QueueLength(LinkQueue Q)
{int count = 0;QNode* p = Q.front->next;while (p){count++;p = p->next;}return count;
}

3.6  入队

//入队
Status EnQueue(LinkQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素QNode* p = new QNode;p->data = e;p->next = NULL;Q.rear->next = p;   //将新结点插入队尾Q.rear = p;         //修改队尾指针return OK;
}

3.7  出队

//出队
Status DeQueue(LinkQueue& Q, QElemType& e)
{//删除队头元素,用e返回其值if (Q.front == Q.rear)return ERROR;   //若队列为空,返回ERRORQNode* p = Q.front->next;e = p->data;  //用e保存头结点数据Q.front->next = p->next;  //修改头结点指针域if (Q.rear == p)Q.rear = Q.front;  //最后一个元素被删除,队尾指针指向头结点delete p;   //释放原队头元素的空间return OK;
}

3.8  获取队头元素

//取队头元素
QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改头指针if (Q.front != Q.rear)return Q.front->next->data;  //返回头元素的值,队头元素不变
}

3.9  输出队列元素

//输出队列元素
void PrintQueue(LinkQueue Q)
{//前提队列不为空printf("(front) ");if (Q.front != Q.rear){QNode* p = Q.front->next;while (p != NULL){printf("%d ", p->data);p = p->next;}}printf("(rear)\n");
}

3.10  整体代码(含测试)

//链队列的实现
#include<iostream>
using namespace std;//初始化定义
#define OK 1
#define ERROR 0
#define OVERFLOW -1
//Status是函数返回值类型,其值是函数结果状态代码
typedef int Status;typedef int QElemType;
typedef struct QNode
{QElemType data;struct QNode* next;
}QNode, *QueuePtr;typedef struct
{QueuePtr front;   //队头指针QueuePtr rear;    //队尾指针
}LinkQueue;//队列初始化
Status InitQueue(LinkQueue& Q)
{//构造一个空队列Q.front = Q.rear = new QNode;  //生成新结点作为头结点,队头和队尾指针指向此结点Q.front->next = NULL;   //头结点的指针域置空return OK;
}//销毁队列
Status DestroyQueue(LinkQueue& Q)
{while (Q.front){Q.rear = Q.front->next;delete Q.front;Q.front = Q.rear;}return OK;
}//求队列中元素数量
int QueueLength(LinkQueue Q)
{int count = 0;QNode* p = Q.front->next;while (p){count++;p = p->next;}return count;
}//入队
Status EnQueue(LinkQueue& Q, QElemType e)
{//插入元素e为Q的新的队尾元素QNode* p = new QNode;p->data = e;p->next = NULL;Q.rear->next = p;   //将新结点插入队尾Q.rear = p;         //修改队尾指针return OK;
}//出队
Status DeQueue(LinkQueue& Q, QElemType& e)
{//删除队头元素,用e返回其值if (Q.front == Q.rear)return ERROR;   //若队列为空,返回ERRORQNode* p = Q.front->next;e = p->data;  //用e保存头结点数据Q.front->next = p->next;  //修改头结点指针域if (Q.rear == p)Q.rear = Q.front;  //最后一个元素被删除,队尾指针指向头结点delete p;   //释放原队头元素的空间return OK;
}//取队头元素
QElemType GetHead(LinkQueue Q)
{//返回Q的队头元素,不修改头指针if (Q.front != Q.rear)return Q.front->next->data;  //返回头元素的值,队头元素不变
}//输出队列元素
void PrintQueue(LinkQueue Q)
{//前提队列不为空printf("(front) ");if (Q.front != Q.rear){QNode* p = Q.front->next;while (p != NULL){printf("%d ", p->data);p = p->next;}}printf("(rear)\n");
}int main()
{LinkQueue Q;QElemType e;cout << "初始化队列..." << endl;if (InitQueue(Q) == OK)cout << "队列初始化成功!" << endl;elsecout << "队列初始化失败!" << endl;cout << "\n测试入队操作:" << endl;for (int i = 1; i <= 5; i++){if (EnQueue(Q, i) == OK)cout << i << " 入队成功" << endl;elsecout << i << " 入队失败" << endl;}cout << "\n当前队列:" << endl;PrintQueue(Q);cout << "\n队列长度:" << QueueLength(Q) << endl;cout << "\n测试出队操作:" << endl;for (int i = 0; i < 3; i++){if (DeQueue(Q, e) == OK)cout << e << " 出队成功" << endl;elsecout << "出队失败,队列可能为空" << endl;}cout << "\n当前队列:" << endl;PrintQueue(Q);cout << "\n队列长度:" << QueueLength(Q) << endl;cout << "\n队头元素:" << GetHead(Q) << endl;cout << "\n销毁队列..." << endl;if (DestroyQueue(Q) == OK)cout << "队列销毁成功!" << endl;elsecout << "队列销毁失败!" << endl;return 0;
}

结语

到此我们队列的基本操作也就完成了,那么我们对于数据结构中的顺序表、栈、队列的学习已经基本完成,可以进行一些简单的力扣题的书写了,这里并没有太大的难度,需要的是不断去熟悉和练习来完成对这部分知识的掌握!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle 闪回版本(闪回表到指定SCN)

1.创建目录 mkdir /u01/app/oracle/flash 2.配置FRA alter system set db_recovery_file_dest_size15G; alter system set db_recovery_file_dest/u01/app/oracle/flash; 3.设置闪回参数--确保可以闪回48h内的数据库 alter system set db_flashback_retention_target2880; 4…

中关村环球时尚产业联盟 东晟时尚产业创新中心成立

2024年9月6日&#xff0c;中关村环球时尚产业联盟与东晟时尚创新科技&#xff08;北京&#xff09;有限公司于中关村科技园东城园举行了隆重的战略合作签约仪式。 中关村科技园东城园领导发表了致辞&#xff0c;并表示东城区作为首都北京的核心区域&#xff0c;拥有深厚的历史…

SW - 装配图旋转到一个想要的正视图

文章目录 SW - 装配图旋转到一个想要的正视图概述笔记将装配图旋转到自己想要的视图的方法保存当前视图选择自己保存的视图END SW - 装配图旋转到一个想要的正视图 概述 在弄装配图。 如果按照SW默认的视图&#xff0c;Y方向是反的。 原因在于我画零件图时&#xff0c;方向就…

从“抄袭”到“原创”:5个超实用的论文降重技巧!

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 每当写完一篇论文&#xff0c;松了一口气准备庆祝时&#xff0c;突然想到还有一个名叫“查重”的终极大Boss等着你&#xff0c;瞬间心情从云端跌入谷底。 是不是你&#xff1f; 很多同学在提交之前&#…

fatfs API使用手册

配置 /*---------------------------------------------------------------------------/ / Configurations of FatFs Module /---------------------------------------------------------------------------*/#define FFCONF_DEF 80286 /* Revision ID *//*---------------…

Spring IoC笔记

目录 1.什么是 IoC&#xff1f; 2.IoC类注解&#xff08;五大注解&#xff09; 2.1那为什么要这么多类注解&#xff1f; 2.2五大注解是不是可以混用&#xff1f; 2.3程序被spring管理的条件是&#xff1f; 3.bean对象 3.1Bean 命名约定 3.2获取bean对象 4.⽅法注解 B…

业绩由盈转亏,全面冲刺大模型的360值得期待吗?

在中国互联网市场上&#xff0c;360无疑是一家大家家喻户晓的公司&#xff0c;从安全软件起家&#xff0c;360的服务已经延展到了市场的方方面面&#xff0c;就在最近360的财报正式公布&#xff0c;很多人都在问360的财报该怎么看&#xff1f;全面冲刺大模型的360值得我们期待吗…

uniapp中uni.request的统一封装 (ts版)

文章目录 前言一、我们为什么要去封装&#xff1f;二、具体实现1.创建一个请求封装文件&#xff1a;2.封装 uni.request&#xff1a;3.如何去使用&#xff1f; 总结 前言 在uniapp中如何去更简洁高效的发送我们的请求&#xff0c;下面就介绍了uni.request()二次封装。 一、我们…

目标检测应用场景—数据集【NO.37】纺织物缺陷检测数据集

写在前面&#xff1a;数据集对应应用场景&#xff0c;不同的应用场景有不同的检测难点以及对应改进方法&#xff0c;本系列整理汇总领域内的数据集&#xff0c;方便大家下载数据集&#xff0c;若无法下载可关注后私信领取。关注免费领取整理好的数据集资料&#xff01;今天分享…

AI大模型面试大纲

大纲 1. 介绍和背景 自我介绍&#xff08;5分钟&#xff09; 了解候选人的教育背景、工作经历和对大模型架构的兴趣。 2. 基础理论和概念&#xff08;30分钟&#xff09; 机器学习基础 解释基本概念&#xff0c;如监督学习、无监督学习和强化学习。 讨论不同的模型类型&#xf…

【Iceberg分析】调研Iceberg中表的原地演变

调研Iceberg中表的原地演变 文章目录 调研Iceberg中表的原地演变原生非分区表文件关系图表的原地演变之表schema演变新增字段new_column文件关系变化图为新增字段写入数据文件关系变化图删除新增字段文件关系变化图新增字段new_column2文件关系变化图删除数据文件关系变化图 原…

uniapp学习(003-1 vue3学习 Part.1)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第11p-第p14的内容 文章目录 vue3使用介绍插值表达式例子时间戳随机数输出函数的值 ref响应式数据变量v-bind 绑…

Python入门:深入了解__init__.py 文件(如何实现动态导入子模块)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 `__init__.py` 的作用示例:📝 如何编写 `__init__.py`1. 空的 `__init__.py`2. 导入子模块3. 初始化代码4. 动态导入子模块📝 编写 `__init__.py` 的技巧和注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 在…

大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

永不失联!遨游双卫星三防手机成为高效应急关键所在

今年9月被戏称为“台风月”&#xff0c;台风“摩羯”、“贝碧嘉”以及热带气旋“普拉桑”接连来袭&#xff0c;极端天气不仅导致了电力中断、道路损毁&#xff0c;更使得传统的通信网络遭受重创&#xff0c;给应急通信保障工作带来了极大的压力。面对“三断”的实战难题&#x…

Web3 游戏周报(9.22 - 9.28)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【9.22-9.28】Web3 游戏行业动态&#xff1a; Axie Infinity 将 Fortune Slips 的冷却时间缩短至 24 小时&#xff0c;从而提高玩家的收入。 Web3 游戏开发商 Darkbright Studios…

SV830C产品介绍

SV830C产品介绍 SV830C是一款由珠海亿智科技有限公司&#xff08;Zhuhai Eeasy Technology Co., Ltd.&#xff0c;品牌名为EEASYTECH&#xff09;倾力打造的专业AI系统级芯片&#xff08;SoC&#xff09;&#xff0c;专为视频编码产品而设计。这款芯片不仅集成了先进的神经网络…

了解客户支持的人工智能:人工智能如何改变客户服务

作者&#xff1a;来自 Elastic Elastic Platform Team 我们都经历过这种情况&#xff1a;走进商店时&#xff0c;看到人工收银台排着长队&#xff0c;而所有自助收银台都是空的。这就是所谓的便捷工具并不那么便捷的情况。曾经&#xff0c;许多客户服务 “解决方案” 也处于这种…

局部整体(七)利用python绘制圆形嵌套图

局部整体&#xff08;七&#xff09;利用python绘制圆形嵌套图 圆形嵌套图&#xff08; Circular Packing&#xff09;简介 将一组组圆形互相嵌套起来&#xff0c;以显示数据的层次关系&#xff0c;类似于矩形树图。数据集中每个实体都由一个圆表示&#xff0c;圆圈大小与其代…

如何选择合适的跨境网络专线?

选择合适的跨境网络专线对于保障企业的国际业务顺畅运行至关重要。以下是一些选择跨境网络专线时可以参考的关键点&#xff1a; 服务商的信誉和经验&#xff1a;首先考察服务商的市场声誉和行业经验。一个好的服务商应该拥有良好的客户评价和成功案例&#xff0c;这表明他们有能…