队列的基本操作——常见队列的对比分析(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://www.hqwc.cn/news/487262.html

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

相关文章

WordPres Bricks Builder 前台RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【软考】系统集成项目管理工程师【总】

引言 本来整理这篇文章的目的是方便自己23年考试用的 效果不错 目标完成。 接下来的目标是把这篇文章 做成参加该软考 小伙伴的唯一参考资料&#xff08;有它就够了&#xff09;来持续更新。。。 这篇文章我将当作一个长周期&#xff08;以年为单位&#xff09;项目运维起来&am…

微服务远程调用Feign

目录 RPC概述 什么是Feign&#xff1f; Ribbon&Feign对比 Feign的设计架构 Spring Cloud Alibaba快速整合Feign Spring Cloud Feign扩展 日志配置 契约配置 通过拦截器实现参数传递 自定义拦截器实现认证逻辑 超时时间配置 RPC概述 微服务之间如何方便优雅的实…

【python】yolo目标检测模型转为onnx,及trt/engine模型的tensorrt轻量级模型部署

代码参考&#xff1a; Tianxiaomo/pytorch-YOLOv4: PyTorch ,ONNX and TensorRT implementation of YOLOv4 (github.com)https://github.com/Tianxiaomo/pytorch-YOLOv4这个大佬对于各种模型转化写的很全&#xff0c;然后我根据自己的需求修改了部分源码&#xff0c;稍微简化了…

【深度学习:人体姿态估计】计算机视觉人体姿态估计完整指南

【深度学习&#xff1a;人体姿态估计】计算机视觉人体姿态估计完整指南 什么是人体姿态估计&#xff1f;2D 人体姿态估计2D 人体姿态估计示例2D 与 3D 人体姿态估计人体姿态估计如何工作&#xff1f; 机器学习中人类姿态估计的挑战用于人体姿态估计的流行机器学习模型#1: OmniP…

基于卷积神经网络的图像去噪

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 基于卷积神经网络的图像去噪 完整代码:基于卷积神经网络的图像去噪.rar资源-CSDN文库 https://download.csdn.net/download/abc9918351…

2.23通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试

驱动代码 #include <linux/init.h> #include <linux/module.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/mod_devicetable.h>#define LED_ON _IOW(l, 1, int) #define L…

H12-821_45

45.如图所示,同一局域网中的四台路由器运行IS-IS,其中R1是DIS.则R2、R3、R4分别和R1建立邻接关系,R2、R3、R4之间不建立邻接关系。 A.正确 B.错误 答案&#xff1a;B 注释&#xff1a; 在广播链路上IS-IS路由器建立邻接关系和OSPF不同&#xff0c;所有IS-IS路由器之间都可以建…

前端项目打包体积分析与优化

一、安装依赖分析工具 npm install webpack-bundle-analyz 二、修改webpack.config.js文件 1、导入上面下载的包 2、在plugins里创建实例 三、启动打包命令 npm run build 会弹出如下界面&#xff1a; 四、优化 1、通过CDN导入react-dom文件 修改webpack.config.js文件里…

Linux环境安装jira

jira 是项目与事务跟踪工具&#xff0c;被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪、项目跟踪和敏捷管理等工作领域。 jira 软件安装包直接搜官网&#xff0c;然后可以选择免费的来下载&#xff1a; 安装 jira 之前&#xff0c;需要 Java 和 mysql 环境的…

大模型+影像:智能手机“上春山”

这个春节假期&#xff0c;一首《上春山》火了。吃瓜群众热热闹闹学了一个假期的“春山学”&#xff0c;了解了抢占C位的各种技巧。 假期过去&#xff0c;开工大吉&#xff0c;手机行业开始抢占今年的C位。那么问题来了&#xff0c;今年智能手机最大的机会点在哪里&#xff1f;答…

主流开发语言和开发环境:探索编程世界的基础

在当今这个快速发展的技术时代&#xff0c;软件开发已经成为推动创新的重要力量。无论是构建下一代应用、开发先进的算法还是创建复杂的系统&#xff0c;选择合适的编程语言和开发环境都是至关重要的。在本文中&#xff0c;我们将探讨当前流行的几种主流开发语言以及它们常用的…