队列的基本操作——常见队列的对比分析(c语言完整代码包含注释)

目录

一、队列

1.1基本概念

1.2基本操作

1.3 队列分类

1.3.1带头队列

1.3.2不带头队列

1.3.3 循环带头队列

1.3.4 循环不带头队列

1.3.5 总结

二、代码实现

2.1带头队列

2.2不带头队列

2.3循环带头队列

2.4循环不带头队列


一、队列

1.1基本概念

        队列(Queue)是一种常见的数据结构,它遵循先进先出(First In First Out, FIFO)的原则,类似于现实生活中排队等待的概念。在队列中,元素按照其插入的顺序排列,最先插入的元素将最先被移除。

  • 队列元素:队列中的每个元素称为一个队列元素,可以是任意类型的数据。
  • 队列头(front):队列的头部,即第一个元素所在的位置,通常用于删除元素操作。
  • 队列尾(rear):队列的尾部,即最后一个元素所在的位置,通常用于插入元素操作。

1.2基本操作

        队列的基本操作主要包括入队和出队两种操作,通过这两种操作可以实现对队列中元素的添加和移除。在使用队列时,需要注意保持操作的顺序,遵循 FIFO 的规则,以确保队列的正确性和有效性。

  • 入队(enqueue):将元素插入到队列的末尾,即在队尾添加一个新元素。

  • 出队(dequeue):从队列的头部移除一个元素,并返回该元素的值。

  • 判空(isEmpty):判断队列是否为空,即队列中是否有元素。

  • 判满(isFull):判断队列是否已满,即队列中的元素数量是否达到上限。

  • 获取队头元素(peek):查看队列头部的元素值,但不移除该元素。

  • 清空队列(clear):移除队列中的所有元素,使队列变为空队列。

  • 获取队列长度(size):返回队列中元素的数量。

1.3 队列分类

1.3.1带头队列

  • front 和 rear 的初始值:在带头的队列中,front 和 rear 的初始值通常都设置为 0,表示头结点的位置。
  • 插入元素:在带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.2不带头队列

  • front 和 rear 的初始值:通常情况下,不带头的队列中,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:在不带头的队列中,插入元素时,先将 rear 加一,再将元素插入到 rear 所指向的位置。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。

1.3.3 循环带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 0,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:先将 front 加一,返回 front 指向的位置的元素。同样地,如果 front 达到数组末尾,可通过取余运算将 front 置为 0。
  • 判空条件:当 front 和 rear 的值相等时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.4 循环不带头队列

  • front 和 rear 的初始值:通常情况下,front 和 rear 的初始值都为 -1,表示队列为空。
  • 插入元素:先将 rear 加一,再将元素插入到 rear 所指向的位置。如果 rear 达到数组末尾,可以通过取余运算将 rear 置为 0,实现循环利用数组空间。
  • 删除元素:在不带头的队列中,删除元素时,先将 front 加一,返回 front 指向的位置的元素。
  • 判空条件:当 front 和 rear 的值相等且等于 -1 时,表示队列为空。
  • 判满条件:当 (rear + 1) % 数组长度 等于 front 的值时,表示队列满。

1.3.5 总结

        总的来说,循环队列带头和不带头在判满和判空上的逻辑是相同的,都是根据指针的位置关系来判断队列状态;而引入头结点的主要作用是简化队列为空和队列满的判断逻辑,使队列操作更加灵活高效。

二、代码实现

2.1带头队列

#include <stdio.h>
#include <stdlib.h>#define SIZE 5// 定义一个Queue结构体表示队列
typedef struct {int items[SIZE];int front;   // 队列头指针,指向头结点int rear;    // 队列尾指针,指向最后一个元素
} Queue;// 创建一个空队列并返回其指针
Queue* createQueue() {Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存queue->front = 0; // 初始化队列头指针queue->rear = 0; // 初始化队列尾指针return queue;
}// 判断队列是否满了
int isFull(Queue *queue) {return (queue->rear == SIZE); // 如果队列尾指针指向最后一个元素的下一个位置,则队列已满
}// 判断队列是否为空
int isEmpty(Queue *queue) {return (queue->front == queue->rear); // 如果队列头指针和尾指针相等,说明队列为空
}// 将元素添加到队列尾部
void enqueue(Queue *queue, int item) {if (isFull(queue)) { // 如果队列已满,打印提示信息printf("队列已满,无法入队。\n");} else {queue->rear++; // 队列尾指针加1queue->items[queue->rear - 1] = item; // 将元素存储到队列尾部printf("%d 入队成功。\n", item); // 打印添加成功信息}
}// 从队列头部移除一个元素并返回其值
int dequeue(Queue *queue) {int item;if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败printf("队列为空,无法出队。\n");return -1;} else {item = queue->items[queue->front]; // 获取队列头部元素的值queue->front++; // 队列头指针加1printf("%d 出队成功。\n", item); // 打印移除成功信息return item; // 返回移除的元素值}
}int main() {Queue *queue = createQueue(); // 创建一个新的队列并获取其指针// 进行入队列和出队列操作enqueue(queue, 10);enqueue(queue, 20);enqueue(queue, 30);dequeue(queue);dequeue(queue);dequeue(queue);dequeue(queue); // 尝试从空队列中出队列free(queue); // 释放队列内存空间return 0;
}

2.2不带头队列

#include <stdio.h>
#include <stdlib.h>#define SIZE 5// 定义一个Queue结构体表示队列
typedef struct {int items[SIZE]; // 存储队列元素的数组int front; // 队列头指针int rear; // 队列尾指针
} Queue;// 创建一个空队列并返回其指针
Queue* createQueue() {Queue *queue = (Queue*)malloc(sizeof(Queue)); // 为队列分配内存queue->front = -1; // 初始化队列头指针queue->rear = -1; // 初始化队列尾指针return queue;
}// 判断队列是否满了
int isFull(Queue *queue) {return (queue->rear == SIZE - 1); // 如果队列尾指针指向最后一个元素,则队列已满
}// 判断队列是否为空
int isEmpty(Queue *queue) {return (queue->front == -1 || queue->front > queue->rear); // 如果队列头指针指向了最后一个元素(队列为空),或指向的元素已经被出队列了,说明队列为空
}// 将元素添加到队列尾部
void enqueue(Queue *queue, int item) {if (isFull(queue)) { // 如果队列已满,打印提示信息printf("队列已满,无法入队。\n");} else {if (queue->front == -1) { // 如果队列为空,将队列头指针设置为0queue->front = 0;}queue->rear++; // 队列尾指针加1queue->items[queue->rear] = item; // 将元素存储到队列尾部printf("%d 入队成功。\n", item); // 打印添加成功信息}
}// 从队列头部移除一个元素并返回其值
int dequeue(Queue *queue) {int item;if (isEmpty(queue)) { // 如果队列为空,打印提示信息并返回-1表示操作失败printf("队列为空,无法出队。\n");return -1;} else {item = queue->items[queue->front]; // 获取队列头部元素的值queue->front++; // 队列头指针加1printf("%d 出队成功。\n", item); // 打印移除成功信息return item; // 返回移除的元素值}
}int main() {Queue *queue = createQueue(); // 创建一个新的队列并获取其指针// 进行入队列和出队列操作enqueue(queue, 10);enqueue(queue, 20);enqueue(queue, 30);dequeue(queue);dequeue(queue);dequeue(queue);dequeue(queue); // 尝试从空队列中出队列free(queue); // 释放队列内存空间return 0;
}

2.3循环带头队列

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 4     // 队列的最大容量,带头// 循环队列结构体
typedef struct {int data[MAX_SIZE];  // 用数组存储队列元素int front;           // 队头指针int rear;            // 队尾指针
} CircularQueue;// 初始化循环队列
void initQueue(CircularQueue *queue) {queue->front = 0;    // 初始时队头指针指向第一个元素queue->rear = 0;     // 初始时队尾指针指向第一个元素
}// 判断队列是否为空
int isEmpty(CircularQueue *queue) {return queue->front == queue->rear;  // 队列为空时,队头指针与队尾指针相等
}// 判断队列是否已满
int isFull(CircularQueue *queue) {return (queue->rear + 1) % MAX_SIZE == queue->front;  // 队列已满时,队尾指针的下一个位置为队头指针
}// 入队操作
void enqueue(CircularQueue *queue, int item) {if (isFull(queue)) {  // 判断队列是否已满printf("队列已满,无法插入新元素\n");} else {queue->data[queue->rear] = item;  // 将新元素插入队尾queue->rear = (queue->rear + 1) % MAX_SIZE;  // 移动队尾指针的位置printf("入队成功: %d\n", item);}
}// 出队操作
int dequeue(CircularQueue *queue) {int item;if (isEmpty(queue)) {  // 判断队列是否为空printf("队列为空,无法出队\n");return -1;} else {item = queue->data[queue->front];  // 取出队头元素queue->front = (queue->front + 1) % MAX_SIZE;  // 移动队头指针的位置printf("出队元素: %d\n", item);return item;}
}// 主函数
int main() {CircularQueue queue;initQueue(&queue);  // 初始化循环队列enqueue(&queue, 1);  // 入队操作enqueue(&queue, 2);enqueue(&queue, 3);enqueue(&queue, 3);dequeue(&queue);  // 出队操作dequeue(&queue);dequeue(&queue);dequeue(&queue);return 0;
}

2.4循环不带头队列

#include <stdio.h>#define MAX_SIZE 5// 定义循环队列结构体,不带头
typedef struct {int data[MAX_SIZE];  // 用数组存储队列元素int front;           // 队头指针int rear;            // 队尾指针
} CircularQueue;// 初始化循环队列
void initQueue(CircularQueue *queue) {queue->front = -1;queue->rear = -1;
}// 判断队列是否为空
int isEmpty(CircularQueue *queue) {return (queue->front == -1 && queue->rear == -1);
}// 判断队列是否已满
int isFull(CircularQueue *queue) {return ((queue->rear + 1) % MAX_SIZE == queue->front);
}// 入队操作
void enqueue(CircularQueue *queue, int value) {if (isFull(queue)) {printf("队列已满,无法入队。\n");} else if (isEmpty(queue)) {queue->front = 0;queue->rear = 0;queue->data[queue->rear] = value;printf("%d 入队成功。\n", value);} else {queue->rear = (queue->rear + 1) % MAX_SIZE;queue->data[queue->rear] = value;printf("%d 入队成功。\n", value);}
}// 出队操作
int dequeue(CircularQueue *queue) {if (isEmpty(queue)) {printf("队列为空,无法出队。\n");return -1;} else {int value = queue->data[queue->front];if (queue->front == queue->rear) {queue->front = -1;queue->rear = -1;} else {queue->front = (queue->front + 1) % MAX_SIZE;}printf("%d 出队成功。\n", value);return value;}
}int main() {CircularQueue queue;initQueue(&queue);// 入队操作enqueue(&queue, 10);enqueue(&queue, 20);enqueue(&queue, 30);enqueue(&queue, 40);enqueue(&queue, 50);enqueue(&queue, 60);  // 队列已满,无法入队// 出队操作dequeue(&queue);dequeue(&queue);dequeue(&queue);dequeue(&queue);dequeue(&queue);dequeue(&queue);  // 队列已空,无法出队return 0;
}

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

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

相关文章

openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响

文章目录 openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响 openGauss学习笔记-227 openGauss性能调优-系统调优-其他因素对LLVM性能的影响 LLVM优化效果不仅依赖于数据库内部具体的实现&#xff0c;还与当前所选择的硬件环境等有关。 表达式调用C…

Ubuntu 20.04.1 共享samba给windows 10

通过ssh登录ubuntu&#xff0c;修改/etc/下的smb配置文件&#xff0c; uidq4932hzh57415u:/work$ cat /etc/samba/smb.conf [global] security ads realm V01.NET workgroup V01 idmap uid 10000-20000 idmap gid 10000-20000 winbind enum users yes winbind enum grou…

pandas/geopandas 笔记:判断地点在不在路网上 不在路网的点和路网的距离

0 导入库 import osimport pandas as pd pd.set_option(display.max_rows,5)import osmnx as oximport geopandas as gpd from shapely.geometry import Point 1 读取数据 假设我们有 如下的数据&#xff1a; 1.1 新加坡室外基站位置数据 cell_stationpd.read_csv(outdoor…

耐腐蚀的液位传感器有哪些

液位传感器在不同的应用环境中有着不同的要求&#xff0c;特别是在需要耐腐蚀性液体的环境中&#xff0c;选择合适的传感器至关重要。对于这种情况&#xff0c;一种常见且有效的选择是不锈钢液位传感器。 不锈钢液位传感器具有耐腐蚀性好、安装简便、功耗低、耐压性强等优点。…

企业计算机服务器中了crypt勒索病毒怎么办,crypt勒索病毒解密数据恢复

计算机服务器设备为企业的生产运营提供了极大便利&#xff0c;企业的重要核心数据大多都存储在计算机服务器中&#xff0c;保护企业计算机服务器免遭勒索病毒攻击&#xff0c;是一项艰巨的工作任务。但即便很多企业都做好的了安全运维工作&#xff0c;依旧免不了被勒索病毒攻击…

shiro 整合 springboot 实战

序言 前面我们学习了如下内容&#xff1a; 5 分钟入门 shiro 安全框架实战笔记 shiro 整合 spring 实战及源码详解 这一节我们来看下如何将 shiro 与 springboot 进行整合。 spring 整合 maven 依赖 <?xml version"1.0" encoding"UTF-8"?> …

Spring Boot应用集成Actuator端点自定义Filter解决未授权访问的漏洞

一、前言 我们知道想要实时监控我们的应用程序的运行状态&#xff0c;比如实时显示一些指标数据&#xff0c;观察每时每刻访问的流量&#xff0c;或者是我们数据库的访问状态等等&#xff0c;需要使用到Actuator组件&#xff0c;但是Actuator有一个访问未授权问题&#xff0c;…

2.21日学习打卡----初学Nginx(一)

2.21日学习打卡 目录: 2.21日学习打卡一. Nginx是什么&#xff1f;概述Nginx 五大应用场景HTTP服务器正向代理反向代理正向代理与反向代理的区别&#xff1a;负载均衡动静分离 为啥使用Nginx? 二.下载Nginx&#xff08;linux&#xff09;环境准备下载Nginx和安装NginxNginx源码…

自定义Chrome的浏览器开发者工具DevTools界面的字体和样式

Chrome浏览器开发者工具默认的字体太小&#xff0c;想要修改但没有相关设置。 外观——字体可以自定义字体&#xff0c;但大小不可以调整。 github上有人给出了方法 整理为中文教程&#xff1a; 1.打开浏览器开发者工具&#xff0c;点开设置——实验&#xff0c;勾上红框设…

Go语言中的流程控制

「万事开头难&#xff0c;视频号500粉直播需要你的助力&#xff01;你的支持是我前进的动力&#xff01;」 1、Golang 中的流程控制 流程控制是每种编程语言控制逻辑走向和执行次序的重要部分&#xff0c;流程控制可以说是一门语言的“经脉”。Go 语言中最常用的流程控制有 if …

一文读懂Linux内核中的Device mapper映射机制

一、 简介 本文总结Device mapper的映射机制。Device mapper是Linux2.6内核中提供的一种逻辑设备到物理设备的映射框架机制&#xff0c;在该机制下&#xff0c;用户可以很方便的根据自己的需要指定实现存储资源的管理策略&#xff0c;当前比较流行的Linux的逻辑卷管理器比如&a…

程序与算法

数据结构是数据组织、存储和运算的总和。在计算机处理的大量数据中,数据结构和算法是相互关联、彼此联系的。对实际问题选择了一种好的数据结构之后,还得有一个好的算法,才可以更好地求解问题。一个算法应该具备以下特征:1. 有穷性;2. 确定性;3. 可行性;4. 输入;5. 输出…

一图揭秘为什么开发者都选择华为云软件开发生产线CodeArts

华为云软件开发生产线CodeArts是一站式、全流程、安全可信的云原生DevSecOps云平台&#xff0c;集华为30年研发实践、前沿研发理念、先进研发工具为一体&#xff0c;覆盖需求、开发、测试、部署等软件交付全生命周期环节&#xff0c;为开发者打造全云化研发体验。 体验通道&am…

如何快速卸载windows电脑的一些软件?

本系列是一些电脑常规操作的普及&#xff0c;有需要借鉴即可 注&#xff1a;每个电脑都会有差异&#xff0c;参考即可。 其实大部分软件你删除桌面上的图标不等于删除&#xff0c;因为桌面上的那个图标就是一个简单的快捷方式而已。 在这里插入图片描述 那如何正确的卸载软件呢…

基于Python3的数据结构与算法 - 04 快速排序

一、快速排序思路 快速排序特点&#xff1a;快 步骤&#xff1a; 取一个元素p&#xff08;第一个元素&#xff09;&#xff0c;使元素p归为&#xff1b;列表被p分成两部分&#xff0c;左边都比p小&#xff0c;右边都比p大&#xff1b;递归完成排序。 因此我们可以得到快速排…

java 面向对象-上:类的结构之二

类的设计中&#xff0c;两个重要结构之二&#xff1a;方法 方法 描述类应该具的功能。 比如&#xff1a;Math类&#xff1a;sqrt()\random() \... Scanner类&#xff1a;nextXxx() ... Arrays类&#xff1a;sort() \ binarySearch() \ toString() \ equals() \ ... 1.举例 p…

H.323

1 H.323 信令标准。 是 ITU-T 于 1996 年制定的为在局域网上传送话音信息的建议书。 1998 年的第二个版本改用的名称是“基于分组的多媒体通信系统”。 H.323 是互联网的端系统之间进行实时声音和视频会议的标准。 H.323 不是一个单独的协议&#xff0c;而是一组协议。包括…

TYPE-C接口桌面显示器:视频与充电的双重革新

在现代科技的浪潮中&#xff0c;TYPE-C接口桌面显示器崭露头角&#xff0c;它不仅仅是一台显示器&#xff0c;更是充电与视频传输的完美融合。这种新型的显示器&#xff0c;凭借其TYPE-C接口&#xff0c;实现了从DC电源到PD协议充电的华丽转身&#xff0c;为众多设备如笔记本电…

【学网攻】 第(30)节 -- 综合实验三

系列文章目录 目录 系列文章目录 文章目录 前言 一、综合实验 二、实验 1.引入 实验目标 实验设备 实验拓扑图 实验配置 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交换机认识及使用【学网攻】 第(3)节 -- 交换机配置聚合端口【学网攻】 第(4)节…

beego代理前端web的bug

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、beego代理前端web的bug总结 一、beego代理前端web的bug *报错&#xff0c;为web压缩包index.html里面的注释被错误解析&#xff0c;删掉就行 2024/02/22 10:2…