数据结构与算法学习笔记四---队列的表示和实现(C++)

目录

前言

1.队列的顺序存储方式的实现

1.定义

2.队列初始化

3.销毁

4.队列是否为空

5.队列长度

6.清空队列

7.队列头元素

8.入队

9.出队

10.完整代码

2.队列的链式存储方式的实现

1.定义

2.队列初始化

3.销毁

4.队列是否为空

5.队列长度

6.清空队列

7.队列头元素

8.入队

9.出队

10.完整代码


前言

    队列也是一中受限的线性表,只能在表的一段进行插入操作,在表的另外一段进行删除操作。和线性表一样,仍然是一对一的关系。存储结构也有两种方式:顺序队列和链队列。运算规则为先进先出。基本操作位入队或者出队,建空队列,判断队列为空或者队列已满等操作。

        队列在现实中也有着很多的应用场景,例如离散事件的模拟、操作系统中的作业调度等。

        队列仅在表尾进行插入操作,在表头进行删除操作。它是一种先进先出的线性表。

        在队首删除元素成为出队,在队尾插入元素成为入队。

1.队列的顺序存储方式的实现

1.定义

#define MAXQSIZE 100 // 最大队列长度struct SeqListQueue{int *base;int front;int rear;
};

2.队列初始化

// 队列初始化
void initQueue(SeqListQueue &seqQueue){seqQueue.base = (int *)malloc(sizeof(int) * MAXQSIZE); // 为队列的数组成员分配内存空间if (!seqQueue.base) {std::cerr << "内存分配失败!" << std::endl;exit(EXIT_FAILURE);}seqQueue.front = seqQueue.rear = 0; // 初始化队列的 front 和 rear 指针
}

3.销毁

// 销毁队列
void destroyQueue(SeqListQueue &seqQueue) {free(seqQueue.base);seqQueue.base = nullptr;seqQueue.front = seqQueue.rear = 0;
}

4.队列是否为空

// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {return seqQueue.front == seqQueue.rear;
}

5.队列长度

// 获取队列长度
int queueLength(SeqListQueue seqQueue) {return (seqQueue.rear - seqQueue.front + MAXQSIZE) % MAXQSIZE;
}

6.清空队列

// 清空队列
void clearQueue(SeqListQueue &seqQueue) {seqQueue.front = seqQueue.rear = 0; // 将 front 和 rear 指针重置为零
}

7.队列头元素

// 获取队列的队首元素
bool getFront(SeqListQueue seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法获取队首元素!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];return true;
}

8.入队

// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {if ((seqQueue.rear + 1) % MAXQSIZE == seqQueue.front) {std::cerr << "队列已满,无法入队!" << std::endl;return false;}seqQueue.base[seqQueue.rear] = element;seqQueue.rear = (seqQueue.rear + 1) % MAXQSIZE;return true;
}

9.出队

// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法出队!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];seqQueue.front = (seqQueue.front + 1) % MAXQSIZE;return true;
}

10.完整代码

#include <iostream>
#include <cstdlib> // for malloc, free#define MAXQSIZE 100 // 最大队列长度struct SeqListQueue{int *base;int front;int rear;
};// 队列初始化
void initQueue(SeqListQueue &seqQueue){seqQueue.base = (int *)malloc(sizeof(int) * MAXQSIZE); // 为队列的数组成员分配内存空间if (!seqQueue.base) {std::cerr << "内存分配失败!" << std::endl;exit(EXIT_FAILURE);}seqQueue.front = seqQueue.rear = 0; // 初始化队列的 front 和 rear 指针
}// 入队
bool enQueue(SeqListQueue &seqQueue, int element) {if ((seqQueue.rear + 1) % MAXQSIZE == seqQueue.front) {std::cerr << "队列已满,无法入队!" << std::endl;return false;}seqQueue.base[seqQueue.rear] = element;seqQueue.rear = (seqQueue.rear + 1) % MAXQSIZE;return true;
}// 出队
bool deQueue(SeqListQueue &seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法出队!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];seqQueue.front = (seqQueue.front + 1) % MAXQSIZE;return true;
}// 输出队列元素
void printQueue(SeqListQueue seqQueue) {int i = seqQueue.front;while (i != seqQueue.rear) {std::cout << seqQueue.base[i] << " ";i = (i + 1) % MAXQSIZE;}std::cout << std::endl;
}// 销毁队列
void destroyQueue(SeqListQueue &seqQueue) {free(seqQueue.base);seqQueue.base = nullptr;seqQueue.front = seqQueue.rear = 0;
}// 判断队列是否为空
bool isEmptyQueue(SeqListQueue seqQueue) {return seqQueue.front == seqQueue.rear;
}// 获取队列长度
int queueLength(SeqListQueue seqQueue) {return (seqQueue.rear - seqQueue.front + MAXQSIZE) % MAXQSIZE;
}// 清空队列
void clearQueue(SeqListQueue &seqQueue) {seqQueue.front = seqQueue.rear = 0; // 将 front 和 rear 指针重置为零
}// 获取队列的队首元素
bool getFront(SeqListQueue seqQueue, int &element) {if (seqQueue.front == seqQueue.rear) {std::cerr << "队列为空,无法获取队首元素!" << std::endl;return false;}element = seqQueue.base[seqQueue.front];return true;
}int main() {SeqListQueue seqQueue;initQueue(seqQueue); // 初始化队列// 测试入队for (int i = 1; i <= 5; ++i) {enQueue(seqQueue, i * 10);}// 输出队列元素std::cout << "队列元素:";printQueue(seqQueue);// 获取队首元素int frontElement;if (getFront(seqQueue, frontElement)) {std::cout << "队首元素:" << frontElement << std::endl;}// 测试出队int element;for (int i = 0; i < 3; ++i) {if (deQueue(seqQueue, element)) {std::cout << "出队元素:" << element << std::endl;}}// 输出队列元素std::cout << "队列元素:";printQueue(seqQueue);// 判断队列是否为空if (isEmptyQueue(seqQueue)) {std::cout << "队列为空" << std::endl;} else {std::cout << "队列不为空" << std::endl;}// 获取队列长度std::cout << "队列长度为:" << queueLength(seqQueue) << std::endl;// 清空队列clearQueue(seqQueue);// 判断队列是否为空if (isEmptyQueue(seqQueue)) {std::cout << "清空队列后,队列为空" << std::endl;} else {std::cout << "清空队列后,队列不为空" << std::endl;}// 销毁队列destroyQueue(seqQueue);return 0;
}

2.队列的链式存储方式的实现

1.定义

typedef struct QNode {int data;          // 元素struct QNode *next;  // 指向下一个节点的指针
} QNode, *QueuePtr;typedef struct {QueuePtr front; // 队首指针QueuePtr rear;  // 队尾指针
} LinkQueue;

2.队列初始化

// 初始化队列
void initQueue(LinkQueue &link) {link.front = link.rear = (QueuePtr)malloc(sizeof(QNode));if (!link.front) {exit(-1); // 内存分配失败}link.front->next = NULL;
}

3.销毁

void destroyQueue(LinkQueue &queue) {QueuePtr p, q;p = queue.front;while (p) {q = p->next;free(p);p = q;}queue.front = queue.rear = nullptr; // 将队首和队尾指针置为空指针
}

4.队列是否为空

// 判断队列是否为空
bool isEmptyQueue(LinkQueue queue) {return queue.front == queue.rear;
}

5.队列长度

// 获取队列长度
int queueLength(LinkQueue queue) {int length = 0;QueuePtr p = queue.front->next;while (p) {length++;p = p->next;}return length;
}

6.清空队列

// 清空队列
void clearQueue(LinkQueue &queue) {QueuePtr p = queue.front->next;while (p) {QueuePtr temp = p;p = p->next;free(temp);}queue.front->next = nullptr;queue.rear = queue.front;
}

7.队列头元素

// 获取队列的头元素
int getFront(LinkQueue queue) {if (isEmptyQueue(queue)) {cout << "队列为空!" << endl;return -1;}return queue.front->next->data;
}

8.入队

// 入队
void enQueue(LinkQueue &queue, int element) {QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); // 申请内存空间if (!p) {exit(-1); // 内存分配失败}p->data = element;p->next = NULL;queue.rear->next = p;queue.rear = p;
}

9.出队

// 出队
int deQueue(LinkQueue &queue, int &element) {if (queue.rear == queue.front) {return 0; // 队列为空}QueuePtr p = queue.front->next;element = p->data;queue.front->next = p->next;if (queue.rear == p) {queue.rear = queue.front;}free(p);return 1;
}

10.完整代码

#include <iostream>
#include <cstdlib> // for malloc, free
using namespace std;typedef int ElementType;typedef struct QNode {int data;          // 元素struct QNode *next;  // 指向下一个节点的指针
} QNode, *QueuePtr;typedef struct {QueuePtr front; // 队首指针QueuePtr rear;  // 队尾指针
} LinkQueue;// 初始化队列
void initQueue(LinkQueue &link) {link.front = link.rear = (QueuePtr)malloc(sizeof(QNode));if (!link.front) {exit(-1); // 内存分配失败}link.front->next = NULL;
}// 入队
void enQueue(LinkQueue &queue, int element) {QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); // 申请内存空间if (!p) {exit(-1); // 内存分配失败}p->data = element;p->next = NULL;queue.rear->next = p;queue.rear = p;
}// 出队
int deQueue(LinkQueue &queue, int &element) {if (queue.rear == queue.front) {return 0; // 队列为空}QueuePtr p = queue.front->next;element = p->data;queue.front->next = p->next;if (queue.rear == p) {queue.rear = queue.front;}free(p);return 1;
}// 销毁队列
void destroyQueue(LinkQueue &queue) {QueuePtr p, q;p = queue.front;while (p) {q = p->next;free(p);p = q;}queue.front = queue.rear = nullptr; // 将队首和队尾指针置为空指针
}// 清空队列
void clearQueue(LinkQueue &queue) {QueuePtr p = queue.front->next;while (p) {QueuePtr temp = p;p = p->next;free(temp);}queue.front->next = nullptr;queue.rear = queue.front;
}// 判断队列是否为空
bool isEmptyQueue(LinkQueue queue) {return queue.front == queue.rear;
}// 获取队列长度
int queueLength(LinkQueue queue) {int length = 0;QueuePtr p = queue.front->next;while (p) {length++;p = p->next;}return length;
}// 获取队列的头元素
int getFront(LinkQueue queue) {if (isEmptyQueue(queue)) {cout << "队列为空!" << endl;return -1;}return queue.front->next->data;
}// 输出队列元素
void printQueue(LinkQueue queue) {QueuePtr p = queue.front->next;while (p) {cout << p->data << " ";p = p->next;}cout << endl;
}int main() {LinkQueue queue;initQueue(queue); // 初始化队列// 测试入队enQueue(queue, 10);enQueue(queue, 20);enQueue(queue, 30);// 输出队列元素cout << "队列元素:";printQueue(queue);// 测试出队int element;if (deQueue(queue, element)) {cout << "出队元素:" << element << endl;} else {cout << "队列为空,无法出队!" << endl;}// 输出队列元素cout << "队列元素:";printQueue(queue);// 清空队列clearQueue(queue);// 测试是否为空if (isEmptyQueue(queue)) {cout << "队列已清空或为空" << endl;} else {cout << "队列不为空" << endl;}// 测试队列长度cout << "队列长度为:" << queueLength(queue) << endl;// 测试获取队列头元素cout << "队列头元素为:" << getFront(queue) << endl;return 0;
}

 3.线性表、栈、队列的区别

        相同点:逻辑结构相同,都是线性的;都可以用顺序存储或者链式存储;栈和队列都是两种特殊的线性表,即受限的线性表(知识对插入、删除运算加以限制)。

        不同点:

1.运算规则不同

        线性表为随机存储,栈只允许在一段进行插入和删除运算,因而是后进先出表LIFO。

        队列是只允许在一段进行插入、另一端进行删除操作,因而是先进先出表FIFO。

2.用途不同

        线性表比较通用;堆栈用于函数调用、递归和简化设计等;队列用于离散事件模拟、OS作业调度和简化设计等。

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

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

相关文章

Jenkins服务器IP更换,Jenkins URL地址更换

服务器的网络地址发生变动&#xff0c;修改jenkins服务器IP地址后&#xff0c;jenkins网页能够打开&#xff0c;但是job中的配置钩子没有自动改变&#xff0c;如图所示&#xff1a; 经过查询资料了解&#xff0c;需要修改jenkins本地化配置地址才可以显示正确&#xff1a; 1、…

初识ansible变量及实例配置

目录 1、为什么要使用变量 2、变量分类 3、 变量详解 3.1 vars,vars_files , group_vars 3.1 .1 vars 剧本中定义变量 3.1.2 vars_file 将变量存放到一个文件中&#xff0c;并在剧本中引用 3.1.3 group_vars 创建一个变量文件给某个组使用 实例1-根据不同的主机…

Java关键字和API

1 this和super关键字 1.this和super的意义 this&#xff1a;当前对象 在构造器和非静态代码块中&#xff0c;表示正在new的对象 在实例方法中&#xff0c;表示调用当前方法的对象 super&#xff1a;引用父类声明的成员 无论是this和super都是和对象有关的。 2.this和sup…

通过实例学C#之序列化与反序列化XmlSerializer类

简介 可以将类序列化成xml文件&#xff0c;或者将xml文件反序列化成类对象&#xff0c;一般用于保存或加载项目参数。 构造函数 XmlSerializer() 不使用函数创建一个xmlSerializer对象。 XmlSerializer(Type type) 使用type对象创建一个xmlSerializer对象&#xff0c;注意&…

lv_table

通过点击lv_table的某一行来选中这一行&#xff0c;以及通过点击另外创建的按钮来删除选中的这一行数据。在table_event_cb回调函数中&#xff0c;我们通过检测点击事件发生的行和列来确定被点击的行&#xff0c;然后在按钮的事件处理器btn_event_cb中&#xff0c;根据之前保存…

洛谷 P3811 [模板] 模意义下的乘法逆元

【模板】模意义下的乘法逆元 题目描述 给定 n , p n,p n,p 求 1 ∼ n 1\sim n 1∼n 中所有整数在模 p p p 意义下的乘法逆元。 这里 a a a 模 p p p 的乘法逆元定义为 a x ≡ 1 ( m o d p ) ax\equiv1\pmod p ax≡1(modp) 的解。 输入格式 一行两个正整数 n , p n,…

Qt——Qt网络编程之获取本机网络信息(通过QHostInfo和QNetworkInterface 类获取本地网络所有接口信息)

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》

asp.net core mvc 路由

在ASP.NET Core MVC中&#xff0c;路由是一项核心功能&#xff0c;它负责将进来的HTTP请求映射到相应的控制器和动作方法上。ASP.NET Core支持两种路由方式&#xff1a;传统的基于模板的路由&#xff08;约定路由&#xff09;和属性路由。 1. 基于约定的路由 在Startup.Confi…

【001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂】

001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂 文章目录 001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂创作背景通信模型ISO/OSI七层模型 和 TCP/IP四层模型网络通信数据包格式&#xff08;Ethernet II&…

【opencv GPU】测测你的opencv-GPU 版本每秒处理帧数 大概多少?

在使用OpenCV的cv2.dnn.Net类从ONNX模型文件创建网络时&#xff0c;如果你想要启用GPU加速&#xff0c;你需要确保OpenCV在安装时已经包含了GPU支持。这通常意味着你需要从源代码编译OpenCV&#xff0c;并确保在编译过程中启用了CUDA支持。 以下是如何在OpenCV中启用GPU加速的…

20240421阿夏的CSDN创作纪念日(3周年)

缘 提示&#xff1a;可以和大家分享最初成为创作者的初心 3年前我写下第一篇CSDN&#xff0c;开启了Python研究之旅win10系统64位&#xff08; 惠普&#xff09;台式电脑自动开机、关机图文详细解&#xff08;一&#xff09;_惠普主板设置自动开机-CSDN博客文章浏览阅读4.2k次…

对观察者模式的理解

目录 一、场景1、题目描述 【[案例来源](https://kamacoder.com/problempage.php?pid1075)】2、输入描述3、输出描述4、输入示例5、输出示例 二、实现三、更复杂的场景 【[案例来源](https://refactoringguru.cn/design-patterns/observer/java/example#example-0--listeners-…

深入OceanBase内部机制:资源隔离实现的方式总结

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 1. 为何HTAP需要资源隔离2. OceanBase的资源隔离机制概述租户间资源隔离租户内资源隔离物理资源隔离大查询请求的隔离优先级…

26.ELF文件解析

ELF文件及objdump/readelf命令 文章目录 ELF文件及objdump/readelf命令ELF文件结构分析使用od命令读取ELF文件使用readelf命令读取ELF文件使用objdump命令分析ELF文件reference 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; ELF(Executa…

4月21敲一篇猜数字游戏,封装函数,void,无限循环,快去体验体验

今天敲一篇猜数字游戏 目录 今天敲一篇猜数字游戏 1.打开先学goto语句&#xff1a; 2.开干&#xff1a; 首次我们学习随机数&#xff1a; 讲解一下&#xff1a; 改用srand; 加入时间变量&#xff1a; 获取时间&#xff1a;哈​编辑 3.我本来想已近够完美了&#xff0…

Flink学习(七)-单词统计

前言 Flink是流批一体的框架。因此既可以处理以流的方式处理&#xff0c;也可以按批次处理。 一、代码基础格式 //1st 设置执行环境 xxxEnvironment env xxxEnvironment.getEnvironment;//2nd 设置流 DataSource xxxDSenv.xxxx();//3rd 设置转换 Xxx transformation xxxDS.…

Spring Boot中接收各种各样的参数

一、接收json参数&#xff0c;封装为Map 1.1、核心代码 /*** 接收json参数&#xff0c;封装为Map* param servletRequest* return* throws Exception*/ PostMapping("/getParam") public R getParam(HttpServletRequest servletRequest) throws Exception {Map<…

Bootstrap 5 保姆级教程(十二):弹出框 消息弹窗

一、弹出框 1.1 创建弹出框 通过向元素添加 data-bs-toggle"popover" 来来创建弹出框。 title 属性的内容为弹出框的标题&#xff0c;data-bs-content 属性显示了弹出框的文本内容&#xff1a; 注意: 弹出框要写在 JavaScript 的初始化代码里。 以下实例可以在文…

NLP 文本表征方式

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;将文本转换成计算机能够理解和处理的格式是一个基本的步骤。这个过程通常被称为文本表征或文本向量化。下面&#xff0c;我将详细介绍几种常见的文本表征方法&#xff0c;并提供一些例子来说明这些技术是如何应用的。…

投入产出表的分析要点有哪些

投入产出分析是利用投入产出表、投入产出系数和投入产出模型&#xff0c;对国民经济各部门之间的技术经济联系和影响进行分析的一种经济数据分析方法。 一、什么是投入产出表 我国的投入产出表是描述国民经济中各种产品的来源与使用去向的棋盘式平衡表 , 是产品部门 产品部门…