数据结构_队列Queue(C语言实现)

一、队列的基本概念

1.队列定义

队列是一种先进先出的线性表数据结构(First in First out),现实中的例子就是,排队购票,先排队的先购票,购完票之后直接从这个队中离开,后来的在这个队后面排队,这就是队列。

如图;
在这里插入图片描述
这就是一个空的队列,从队尾入队,从队头出队

2.常见的基本操作

  • initQueue:初始化队列
  • empty: 判断队列是否为空
  • push:入队操作
  • pop:出队操作
  • Front:获取队头元素

3.数据结构定义

为了锻炼高度模块化(分层设计),这里我们直接嵌套,不在Queue中直接定义数组,而是重新抽象出一个独立的vector数据结构作为底层容器,让Queue通过组合的方式使用vector来实现其功能。这种设计强调关注点分离,将内存管理的职责交给vector模块,而Queue模块只需专注于队列特有的逻辑操作。

typedef struct Queue {vector* data;int size,head,tail;//size记录当前队列有多少元素
}Queue;

二、代码实现

首先引用头文件,宏定义队列的开始元素为多少,定义vector及Queue

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <stdbool.h>
#define BEGIN_SIZE 6
typedef struct vector {int* val;int size;//记录当前容量
}vector;
typedef struct Queue {vector* data;int size,head,tail;//size记录当前队列有多少元素
}Queue;

初始化Queue

Queue *initQueue() {Queue* q = (Queue*)malloc(sizeof(Queue));q->data = initVector();q->head = q->tail = q->size = 0;return q;
}

要想初始化Queue,那么也就要初始化vector

vector* initVector()
{vector * v=(vector*)malloc(sizeof(vector));v->size = BEGIN_SIZE;v->val = (int*)malloc(sizeof(int) * BEGIN_SIZE);return v;
}

这样队列的初始化就实现了,下来我们依次实现队列的基本功能:

  • empty: 判断队列是否为空
  • push:入队操作
  • pop:出队操作
  • Front:获取队头元素

empty():

bool empty(Queue* q) {return q->size == 0;//如果当前元素的个数等于 0 ,那么则证明队列为空
}

push():

int push(Queue* q, int val) {checkFull(q); /*如果队列已经满了,扩容队列*/q->data->val[q->tail++] = val;q->size++;return 1;
}

pop():

int pop(Queue* q) {if (empty(q))/*如果队列为空的话,则返回-1代表弹出失败*/ {printf("pop: 队列为空\n");return -1;}int count = 0;while (count < q->tail - 1) {q->data->val[count] = q->data->val[count + 1];count++;}q->tail--;q->size--;return 1;
}

解释下,这里为什么count<q->tail-1 为什么不是 count<q->tail
例如,队列中有三个元素,那么tail的值就是3,count从0开始,一共要循环到3次,最后一次的count等于 2 ,这个时候 q->data->val[count] = q->data->val[count + 1];这一句就会变为q->data->val[2] = q->data->val[3];,此时 3 这个位置是tail的位置,在内存中并没有赋值,内存中的值是未定义的(可能是垃圾值)

Front():

int Front(Queue* q) {if (empty(q)) {printf("Front 队列为空\n");return -1;}return q->data->val[q->head];
}

反过头处理checkFull(),检查队列是否为满,满的话则需要扩容

checkFull():

void checkFull(Queue *q) {if (q->size == q->data->size) {int newSize = q->data->size * 2;int * newVal=(int *)realloc(q->data->val, sizeof(int) * newSize);if (newVal == NULL) {printf("error checkFull\n");exit(-1);}q->data->val = newVal;q->data->size = newSize;}return;
}

查看队列所有元素

outAll():

void outAll(Queue* q) {printf("Queue: ");for (int i = q->head; i < q->tail; i++) {printf("%3d ", q->data->val[i]);}printf("\n");return;
}

最后释放内存

freeQueue():

void freeQueue(Queue* q) {freeVector(q->data);free(q);return;
}

freeVector():

void freeVector(vector* v) {free(v->val);free(v);return;
}

main函数(测试函数)

int main() {Queue* q = initQueue();//初始化一个队列pop(q);//在空队列时弹出,应该输出 pop: 队列为空Front(q);//在空队列时获取队头元素,应该输出 Front: 队列为空srand(time(NULL));
#define MAX_OP 10for (int i = 0; i < MAX_OP; i++) {int op = rand() % 5, val = rand() % 100;switch (op) {case 0://pop操作printf("front of queue %d 弹出此元素\n", Front(q));pop(q);break;case 1:case 2:case 3:case 4://push操作printf("将 %d push进队列\n", val);push(q, val);break;}outAll(q);}printf("队头元素为: %3d\n",Front(q));return 0;
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define BEGIN_SIZE 6
typedef struct vector {int* val;int size;//记录当前容量
}vector;
typedef struct Queue {vector* data;int size, head, tail;//size记录当前队列有多少元素
}Queue;
vector* initVector()
{vector * v=(vector*)malloc(sizeof(vector));if (v == NULL) {printf("error initVector\n");exit(-1);}v->size = BEGIN_SIZE;v->val = (int*)malloc(sizeof(int) * BEGIN_SIZE);return v;
}
Queue *initQueue() {Queue *q = (Queue*)malloc(sizeof(Queue));if (q == NULL) {printf("error initQueue\n");exit(-1);}q->data = initVector();q->head = q->tail = q->size = 0;return q;
}
bool empty(Queue* q) {return q->size == 0;
}
void checkFull(Queue *q) {if (q->size == q->data->size) {int newSize = q->data->size * 2;int * newVal=(int *)realloc(q->data->val, sizeof(int) * newSize);if (newVal == NULL) {printf("error checkFull\n");exit(-1);}q->data->val = newVal;q->data->size = newSize;}return;
}
int push(Queue* q, int val) {checkFull(q); /*如果队列已经满了,扩容队列*/q->data->val[q->tail++] = val;q->size++;return 1;
}int pop(Queue* q) {if (empty(q))/*如果队列为空的话,则返回-1代表弹出失败*/ {printf("pop: 队列为空\n");return -1;}int count = 0;while (count < q->tail - 1) {q->data->val[count] = q->data->val[count + 1];count++;}q->tail--;q->size--;return 1;
}int Front(Queue* q) {if (empty(q)) {printf("Front: 队列为空\n");return -1;}return q->data->val[q->head];
}void outAll(Queue* q) {printf("Queue: ");if (empty(q)) {printf("NULL\n");return;}for (int i = q->head; i < q->tail; i++) {printf("%3d ", q->data->val[i]);}printf("\n");return;
}void freeVector(vector* v) {free(v->val);free(v);return;
}void freeQueue(Queue* q) {freeVector(q->data);free(q);return;
}int main() {Queue* q = initQueue();//初始化一个队列pop(q);//在空队列时弹出,应该输出 pop: 队列为空Front(q);//在空队列时获取队头元素,应该输出 Front: 队列为空srand(time(NULL));
#define MAX_OP 10for (int i = 0; i < MAX_OP; i++) {int op = rand() % 5, val = rand() % 100;switch (op) {case 0://pop操作printf("front of queue %d 弹出此元素\n", Front(q));pop(q);break;case 1:case 2:case 3:case 4://push操作printf("将 %d push进队列\n", val);push(q, val);break;}outAll(q);}printf("队头元素为: %3d\n",Front(q));return 0;
}

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

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

相关文章

C++对CPU缓存的合理利用

缓存体系 在计算机的体系结构中,存储速度是分了好几层: CPU缓存,又分成了L1/L2/L3等多层缓存,我们暂时看成同一层。访问速度最快 内存,访问速度次之,大概是CPU缓存的几十分之一 硬盘,访问速度最慢,是内存访问速度的几十分之一 所以,在计算机体系结构中,把下一层的数…

贝叶斯定理:理解概率更新与实际场景应用

贝叶斯定理及其应用&#xff1a;从基础到实战 贝叶斯定理&#xff08;Bayes’ Theorem&#xff09;是概率论中最基础也是最强大的工具之一。它通过将先验知识与新证据结合&#xff0c;能够帮助我们在不确定的情况下做出更加精准的判断。本文将从贝叶斯定理的核心概念、公式开始…

组件之间的传递参数传递(常用父向子传递)

现在&#xff0c;有子组件<MdsWxSourceDetailref"mdsWx":rank-obj"activeRankObj":media-name"activeObj.mediaName" :error-info"activeErrorInfo" ></MdsWxSourceDetail>以上代码在MdsIndexRankDetail&#xff0…

java毕业设计-基于springboot区块链的电子病历数据共享平台设计与实现(附源码数据库文档资料)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【新启航】3D 逆向抄数的三维能力架构:数据采集工具操作 × 几何处理算法应用 × 行业场景适配技能

摘要3D 逆向抄数的落地效果依赖多维度能力协同&#xff0c;本文提出 “数据采集工具操作 - 几何处理算法应用 - 行业场景适配技能” 的三维能力架构。通过拆解各维度核心要素&#xff0c;分析数据采集工具&#xff08;激光、结构光等&#xff09;的操作要点&#xff0c;解析几何…

RocksDB 在 macOS M 系列 上运行时报错的解决方案

问题现象 项目中引入可Kafka Stream &#xff0c;Windows下启动不报错 &#xff0c;但是在 macOS M系列 环境下就会报错&#xff0c;初步定位是使用 Java 项目调用 RocksDB 时&#xff0c;运行过程中出现以下报错&#xff1a; UnsatisfiedLinkError: no rocksdbjni in java.lib…

深度学习之第五课卷积神经网络 (CNN)如何训练自己的数据集(食物分类)

简介 之前一直使用的是现有人家的数据集&#xff0c;现在我们将使用自己的数据集进行训练。 基于卷积神经网络 (CNN) 的 MNIST 手写数字识别模型 一、训练自己数据集 1.数据预处理 我们现在有这样的数据集如下图&#xff1a; 每一个文件夹里面有着对应的图片。我们要将这些…

【Big Data】AI赋能的ClickHouse 2.0:从JIT编译到LLM查询优化,下一代OLAP引擎进化路径

目录 1. 什么是ClickHouse&#xff1f; 2. 诞生背景与发展历程 3. 架构设计解析 3.1 存储引擎&#xff1a;MergeTree家族 3.2 分布式模型&#xff1a;分片与副本 3.3 执行流程&#xff1a;向量化与并行计算 4. 解决的问题与适用场景 4.1 典型问题 4.2 适用场景 5. 关…

Vue实践篇-02,AI生成代码

问题描述这个是需求&#xff1a;动态表格、表格里边下拉框&#xff0c;弹框选择基础的列表&#xff0c;还行&#xff0c;这种真的是一时不知如何是好。打算晚上吃了饭找前端同事&#xff0c;帮忙看看。晚饭前&#xff0c;AI一下看看。结果&#xff0c;惊为天人&#xff01;&…

2025-08-28-zabbix5.0创建监控项通过脚本简单实现监控oracle11g的磁盘组和表空间的使用量

title: zabbix5.0创建监控项通过脚本简单实现监控oracle11g的磁盘组和表空间的使用量 authors: Loong date: 2025-08-28使用SQLPLUS配合crontab任务 用来执行sql获取信息的脚本 /home/oracle/zabbix_oracle_check.sh #!/bin/bash #用于zabbix agent被动模式的 非入侵性的检测 #…

MySQL-Redo Log(重做日志)

MySQL 的 Redo Log&#xff08;重做日志&#xff09;是 InnoDB 存储引擎的核心组件之一&#xff0c;是保证数据库持久性&#xff08;Durability&#xff09; 和崩溃恢复&#xff08;Crash Recovery&#xff09; 的关键机制。1. 什么是 Redo Log&#xff1f;它的核心作用是什么&…

嵌入式linux相机(2)

本人从0开始学习linux&#xff0c;使用的是韦东山的教程&#xff0c;在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。本人将前几章的内容大致学完之后&#xff0c;考虑到后续驱动方面得更多的开始实操&#xff0c;后续的内容将以韦东山教程Linux项目的内容…

云计算学习100天-第34天 -zabbix监控2

SourceURL:file:///home/student/Documents/zabbix.doczabbix服务器配置1. 拷贝zabbix软件包到pubserver#在此之前先从真机拷贝安装包[rootserver1 ~]# scp /linux-soft/s2/zzg/zabbix_soft/*.rpm 192.168.88.5:/root/#然后拷贝到pubserver[rootzabbixserver ~]# scp /linux-so…

猫头虎AI分享:无需OCR,基于ColQwen2、Qwen2.5和Weaviate对PDF进行多模态RAG的解决方案

无需OCR&#xff0c;基于ColQwen2、Qwen2.5和Weaviate对PDF进行多模态RAG的解决方案 关键词&#xff1a;多模态RAG、ColQwen2、Qwen2.5-VL、Weaviate 向量数据库、PDF 检索问答、无需 OCR、ColBERT 多向量、跨模态检索、MaxSim 相似度、知识库构建、AI 文档处理、视觉语言模型、…

HTML第三课:特殊元素

HTML第三课&#xff1a;特殊元素特殊元素代码展示特殊元素 不在行级元素和块级元素概念里面的元素无法控制没有宽高的元素 代码展示 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewpo…

蓝桥杯算法之基础知识(5)

目录 Ⅰ.in方法的使用 Ⅱ.字典的使用 Ⅲ.1MB 、KB、 B、 b(即bit)的转换&#xff08;必学&#xff09; Ⅳ.闰年or平年 Ⅴ.count和counter方法 1. count() 方法的使用场景 2. Counter 类的介绍 3. count() 与 Counter 的区别 4. Counter 的高级应用 5.Counter的另一种使用 Ⅵ.ma…

lesson52:CSS进阶指南:雪碧图与边框技术的创新应用

目录 一、CSS雪碧图&#xff1a;从性能优化到交互革命 1.1 技术原理与现代价值 1.2 2025年实现工具与自动化流程 1.2.1 构建工具集成方案 1.2.2 在线生成工具推荐 1.3 高级应用案例与代码实现 1.3.1 多状态按钮系统 1.3.2 响应式雪碧图实现 1.4 最佳实践与性能优化 二…

案例——从零开始搭建 ASP.NET Core 健康检查实例

1. 项目创建与基础设置 创建新项目 首先&#xff0c;创建一个新的 ASP.NET Core Web API 项目&#xff1a; dotnet new webapi -n HealthCheckDemo cd HealthCheckDemo添加必要的 NuGet 包 添加健康检查相关的 NuGet 包&#xff1a; dotnet add package Microsoft.AspNetCore.D…

【Java生产级避坑指南】8. Tomcat线程池下的内存地雷:ThreadLocal泄漏检测与实战解决

摘要:某金融交易系统(Spring Boot 2.7 + Tomcat 9)在线上运行时出现严重内存泄漏:堆内存(4GB)72小时内耗尽并触发OOM,日均200万请求场景下,Full GC频率从正常1次/天飙升至6次/小时。排查发现,根源是ThreadLocal未清理——Tomcat线程池复用线程时,UserInfo等大对象被T…

云端职达:你的AI求职专属猎头,颠覆传统招聘模式

在求职的“金三银四”或“金九银十”&#xff0c;每一分每一秒都弥足珍贵。面对浩如烟海的招聘信息&#xff0c;你是否还在花费大量时间一条条筛选、重复投递简历&#xff0c;最终却常常石沉大海&#xff1f;传统求职方式的低效和“已读不回”的窘境&#xff0c;让许多求职者感…