从零开始的敲代码生活--数据结构篇(队列)

发布时间:2026/8/25 15:15:21

从零开始的敲代码生活--数据结构篇(队列)
一、队列基础概念队列一种允许从一端插入数据另外一端删除数据的线性存储结构称为队列。 把数据插入的这端称为队列的队尾数据删除这端称为队列的队头。 插入操作称为入队删除操作称为出队。特点先进先出、后进后出(FIFO)应用数据缓存队列的 API创建队列入队遍历判空(循环队列还需判满)出队获取队头元素销毁队列分类链式队列链式存储结构实现利用链表结点动态分配内存不存在假溢出问题循环队列顺序结构(数组)实现为避免假溢出使顺序队列成为一种尾首相接的存储方式判空head tail判满(tail 1) % 容量 head牺牲一个存储单元区分空与满文件说明文件说明linkqueue.h头文件链式队列结构体定义 函数声明linkqueue.c源文件链式队列所有功能实现文件说明main.c链式队列测试 main 函数cyclequeue.h头文件循环队列结构体定义 函数声明cyclequeue.c源文件循环队列所有功能实现main.c循环队列测试 main 函数二、链式队列1. 头文件 linkqueue.h#ifndef _LINKQUEUE_H #define _LINKQUEUE_H #include stdio.h #include stdlib.h typedef int Data_t; /* 队列结点结构体:数据域 指针域 */ typedef struct node { Data_t data; // 数据域:保存的数据 struct node *pnext; // 指针域:下一个结点的地址 }Node_t; /* 队列对象结构体:队头指针 队尾指针 结点计数 */ typedef struct lqueue { Node_t *phead; // 队头指针 Node_t *ptail; // 队尾指针 int clen; // 队列当前结点个数 }LQue_t; extern LQue_t *create_link_queue(); extern int en_link_queue(LQue_t *pqlink,Data_t data); extern int show_link_queue(LQue_t *pqlink); extern int de_link_queue(LQue_t *pqlink,Data_t *data); extern int free_link_queue(LQue_t *pqlink); extern int get_link_queue_head(LQue_t *pqlink,Data_t *data); #endif2. 功能实现 linkqueue.ccreate_link_queue 创建队列功能分配队列管理结构体初始化队头指针 phead 置 NULL、队尾指针 ptail 置 NULL、结点计数clen 为 0。返回队列指针malloc 失败返回 NULL。LQue_t *create_link_queue() { LQue_t *pqlink malloc(sizeof(LQue_t)); if(pqlink NULL) { printf(malloc error\n); return NULL; } pqlink-clen 0; pqlink-phead NULL; pqlink-ptail NULL; return pqlink; }en_link_queue 入队功能在队尾插入新结点(尾插法)。队列为空时队头、队尾都指向新结点队列非空时原队尾结点指向新结点更新队尾指针计数自增。返回0 成功-1 失败(malloc 失败)。int en_link_queue(LQue_t *pqlink,Data_t data) { Node_t *pnode malloc(sizeof(Node_t)); if(pnode NULL) { printf(malloc error\n); return -1; } pnode-data data; pnode-pnext NULL; if(pqlink-clen 0) { pqlink-phead pnode; pqlink-ptail pnode; pqlink-clen; } else { pqlink-ptail-pnext pnode; pqlink-ptail pnode; pqlink-clen; } return 0; }de_link_queue 出队功能删除队头结点并带回其数据。结点数 ≥ 2 时队头指针后移一位后释放旧队头结点数 1 时释放后队头、队尾都置 NULL。返回0 成功-1 失败(空队列)。int de_link_queue(LQue_t *pqlink,Data_t *data) { Node_t *pfree pqlink-phead; if(pfree NULL) { return -1; } if(pqlink-clen 2) { pqlink-phead pfree-pnext; *data pfree-data; free(pfree); pqlink-clen--; return 0; } else if(pqlink-clen 1) { *data pfree-data; free(pfree); pqlink-phead NULL; pqlink-ptail NULL; pqlink-clen 0; return 0; } }get_link_queue_head 获取队头元素功能读取队头结点的 data 数据不删除结点。返回0 成功-1 失败(空队列)。int get_link_queue_head(LQue_t *pqlink,Data_t *data) { Node_t *ptemp pqlink-phead; if(ptemp ! NULL) { *data ptemp-data; return 0; } return -1; }show_link_queue 遍历打印队列功能从队头开始循环遍历打印队列中所有 data 数据。返回0 成功-1 失败(空队列)。int show_link_queue(LQue_t *pqlink) { Node_t *pnode pqlink-phead; if(pnode NULL) { return -1; } while(pnode ! NULL) { printf(%d ,pnode-data); pnode pnode-pnext; } printf(\n); return 0; }free_link_queue 销毁队列功能循环释放全部数据结点最后释放队列管理结构体。返回0 成功-1 失败(空队列/入参错误)。int free_link_queue(LQue_t *pqlink) { Node_t *pfree pqlink-phead; Node_t *ptemp NULL; if(pfree NULL) return -1; while(pfree ! NULL) { ptemp pfree-pnext; free(pfree); pfree ptemp; } pqlink-clen 0; pqlink-phead NULL; pqlink-ptail NULL; free(pqlink); return 0; }3. 测试 main 函数 main.c#include linkqueue.h int main(void) { LQue_t *pqlink NULL; Data_t data 0; pqlink create_link_queue(); if(pqlink NULL) { return -1; } en_link_queue(pqlink,1); en_link_queue(pqlink,2); en_link_queue(pqlink,3); en_link_queue(pqlink,4); en_link_queue(pqlink,5); show_link_queue(pqlink); printf(----------\n); de_link_queue(pqlink,data); show_link_queue(pqlink); printf(----------\n); free_link_queue(pqlink); return 0; }4. 编译运行 内存检测编译gcc main.c linkqueue.c -o linkqueue_demo运行程序./linkqueue_demovalgrind 检测内存泄漏写队列务必检测内存泄漏保证每一块 malloc 都有对应的 freevalgrind --leak-checkfull ./linkqueue_demo运行输出结果1 2 3 4 5 2 3 4 5三、循环队列1. 头文件 cyclequeue.h#ifndef _CYCLEQUEUE_H #define _CYCLEQUEUE_H #include stdio.h #include stdlib.h #define CYCQUE 10 //循环队列容量(最多存储 CYCQUE-1 个元素) typedef int Data_t; /* 循环队列对象结构体:数组空间首地址 队头下标 队尾下标 */ typedef struct cycle_queue { Data_t *pbase; // 存储数据的一维数组首地址 int head; // 队头下标 int tail; // 队尾下标 }CQue_t; extern CQue_t *create_cyclequeue(); extern int is_empty_cycle_queue(CQue_t *pcque); extern int is_full_cycle_queue(CQue_t *pcque); extern int en_cycle_queue(CQue_t *pcque,Data_t data); extern int de_cycle_queue(CQue_t *pcque,Data_t *data); extern int show_cycle_queue(CQue_t *pcque); extern int get_cyclequeue_head(CQue_t *pcque,Data_t *data); extern void free_cycqueue(CQue_t *pcque); #endif2. 功能实现 cyclequeue.ccreate_cyclequeue 创建队列功能分配队列管理结构体并分配容量为 CYCQUE 的数组空间初始化队头下标 head 为 0、队尾下标 tail 为 0。返回队列指针malloc 失败返回 NULL。CQue_t *create_cyclequeue() { CQue_t *pcque malloc(sizeof(CQue_t)); if(pcque NULL) { printf(malloc fail\n); return NULL; } pcque-pbase malloc(sizeof(Data_t)*CYCQUE); if(pcque-pbase NULL) { printf(malloc fail\n); free(pcque); return NULL; } pcque-head 0; pcque-tail 0; return pcque; }is_empty_cycle_queue 判空功能队头下标等于队尾下标即为空队列。返回1 空0 非空-1 入参为 NULL。int is_empty_cycle_queue(CQue_t *pcque) { if(pcque NULL) { return -1; } else { return pcque-head pcque-tail; } }is_full_cycle_queue 判满功能队尾下标再走一步就追上队头下标即为满队列(牺牲一个存储单元区分空与满)。返回1 满0 未满-1 入参为 NULL。int is_full_cycle_queue(CQue_t *pcque) { if(pcque NULL) { return -1; } else { return (pcque-tail1) % CYCQUE pcque-head; } }en_cycle_queue 入队功能在队尾下标处写入数据队尾下标按(tail1)%CYCQUE循环后移。队列满时入队失败。返回0 成功-1 失败(队列满或入参为 NULL)。int en_cycle_queue(CQue_t *pcque,Data_t data) { if(pcque NULL) { return -1; } if(is_full_cycle_queue(pcque) ! 0) { return -1; } pcque-pbase[pcque-tail] data; pcque-tail (pcque-tail1) % CYCQUE; return 0; }de_cycle_queue 出队功能读取队头下标处的数据队头下标按(head1)%CYCQUE循环后移。空队列时出队失败。返回0 成功-1 失败(空队列或入参为 NULL)。int de_cycle_queue(CQue_t *pcque,Data_t *data) { if(pcque NULL) { return -1; } if(is_empty_cycle_queue(pcque) ! 0) { return -1; } *data pcque-pbase[pcque-head]; pcque-head (pcque-head1) % CYCQUE; return 0; }get_cyclequeue_head 获取队头元素功能读取队头下标的元素但不删除。返回0 成功-1 失败(空队列或入参为 NULL)。int get_cyclequeue_head(CQue_t *pcque,Data_t *data) { if(pcque NULL) { return -1; } if(is_empty_cycle_queue(pcque) ! 0) { return -1; } *data pcque-pbase[pcque-head]; return 0; }show_cycle_queue 遍历打印队列功能从队头下标开始按循环方式依次遍历到队尾下标打印所有数据。返回0 成功-1 失败(入参为 NULL)。int show_cycle_queue(CQue_t *pcque) { if(pcque NULL) { return -1; } int ptemp pcque-head; while(ptemp ! pcque-tail) { printf(%d ,pcque-pbase[ptemp]); ptemp (ptemp1) % CYCQUE; } printf(\n); return 0; }free_cycqueue 销毁队列功能先释放数组空间再释放队列管理结构体。void free_cycqueue(CQue_t *pcque) { if(pcque NULL) { return; } free(pcque-pbase); free(pcque); return; }3. 测试 main 函数 main.c#include cyclequeue.h int main(void) { CQue_t *pcque create_cyclequeue(); Data_t data; en_cycle_queue(pcque,1); en_cycle_queue(pcque,2); en_cycle_queue(pcque,3); en_cycle_queue(pcque,4); en_cycle_queue(pcque,5); show_cycle_queue(pcque); printf(----------\n); de_cycle_queue(pcque,data); printf(----------\n); show_cycle_queue(pcque); free_cycqueue(pcque); return 0; }4. 编译运行 内存检测编译gcc main.c cyclequeue.c -o cyclequeue_demo运行程序./cyclequeue_demovalgrind 检测内存泄漏写队列务必检测内存泄漏保证每一块 malloc 都有对应的 freevalgrind --leak-checkfull ./cyclequeue_demo运行输出结果1 2 3 4 5 2 3 4 5四、链式队列与循环队列对比对比项链式队列循环队列存储结构链式存储(链表结点)顺序存储(数组)空间动态分配按需申请需要预分配固定容量判空clen 0 / phead NULLhead tail判满一般无需判满(tail1) % CYCQUE head假溢出不存在通过取模循环解决缺点指针域额外占用内存容量固定扩容不便

相关新闻

ABAP 到底有没有自己的 npm registry,从 SAP Package、abapGit、gCTS 一路看到 apm Registry

ABAP 到底有没有自己的 npm registry,从 SAP Package、abapGit、gCTS 一路看到 apm Registry

2026/8/25 15:15:21

2026 年再讨论这个问题,答案已经不能简单停留在「ABAP 没有 npm」这一层。ABAP 生态过去确实长期缺少一个真正对应 npm registry 的东西,但现在已经出现了相当接近 npm 思路的实现。特别是 ABAP Package Manager,也就是 apm,已经建立了自己的 apm Registry,并且公开展示了…

一场 MySQL 默认值引发的血案

一场 MySQL 默认值引发的血案

2026/8/25 15:05:21

目录问题本质场景还原脏数据从何而来:MySQL 隐式默认值根因分析1. MySQL 隐式类型转换规则2. EXPLAIN 行为对比3. MyBatis Plus selectOne() 源码故障链路全景解决方案方案 A:入参前置校验 — 快速止血方案 B:显式类型约束 — 根源修复方案 B…

数据采集+AI分析:Python公开数据采集赋能业务智能化实战

数据采集+AI分析:Python公开数据采集赋能业务智能化实战

2026/8/25 15:05:21

做业务运营、市场分析的人大概率都有过这种体验:做竞品价格监控,得每天挨个刷十几个商品页手动记录;做行业舆情分析,要翻几十篇资讯和用户评论人工整理;做供需趋势判断,全靠零散信息拍脑袋,数据滞后不说,准确性也没法保证。 人工采集加人工分析的模式,在数据量小的时…

【电子设计·AI协作】⑦ Gate 4 期末答辩:你的项目经得起追问吗

【电子设计·AI协作】⑦ Gate 4 期末答辩:你的项目经得起追问吗

2026/8/25 15:55:23

> 适用课程:电子设计(本科) | ESP32 Arduino | 36学时Gate 4 是什么 第9次上课,学期最后一周。你已经走完了:方案设计→Gate 1评审→开发实现→Gate 2审查→Gate 3脱敏考核。现在是最后一关。 Gate 4 的核心任务&a…

P/Invoke全栈解析:从参数封送到栈切换的跨域协作

P/Invoke全栈解析:从参数封送到栈切换的跨域协作

2026/8/25 15:55:23

开场引入 想象这样的场景:你的 Unity 项目已经写了三年的纯 C# 逻辑,突然要接入一套用 C++ 写的高性能物理引擎;或者老板甩过来一段只暴露 C 头文件的系统 API;又或者你必须调用某个厂商只提供原生 SDK 的第三方库。此时你面对的不是"用不用 C#"的选择题,而是&…

Spark大数据分析与实战笔记(第九章 综合案例—Spark实时交易数据统计-02)

Spark大数据分析与实战笔记(第九章 综合案例—Spark实时交易数据统计-02)

2026/8/25 15:55:23

文章目录每日一句正能量第9章 综合案例—Spark实时交易数据统计章节概要9.3 模块开发—构建工程结构9.4 模块开发—构建订单系统9.4.1 模拟订单数据9.4.2 向Kafka集群发送订单数据9.5 模块开发 — 分析订单数据每日一句正能量 活在自己的热爱里,而不是别人的眼光里。…

Python 详解:从语法基础到进阶实战

Python 详解:从语法基础到进阶实战

2026/8/25 15:55:23

1. Python 简介 Python 是一门简洁、易读、功能强大的高级编程语言,由 Guido van Rossum 在 1991 年首次发布。它强调代码可读性,用缩进表达代码块,拥有丰富的标准库和第三方生态,被广泛应用于 Web 开发、数据分析、人工智能、自动…

PyTorch深度学习与实践【03】【数据的三种类型及其编码方案】

PyTorch深度学习与实践【03】【数据的三种类型及其编码方案】

2026/8/25 15:55:23

一、数据的三种类型 (一)连续值(比例 / 区间尺度) 数值之间的差值、倍数有实际物理含义。例子:重量 3kg,10kg。10‑37,代表重量差 7kg;10kg 是 3kg 的三倍重。 葡萄酒里面酒精度、酸…

辽宁智慧校园平台建设方案怎么选?几点实用经验帮你少走弯路

辽宁智慧校园平台建设方案怎么选?几点实用经验帮你少走弯路

2026/8/25 15:45:22

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/24 19:53:32

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/24 19:56:07

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/24 21:16:09

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

2026/8/25 0:04:34

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory Meta Description:GetQzonehistory 是一个QQ空间历史说…

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

2026/8/25 0:04:35

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

2026/8/25 0:04:35

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server! 项目地址: https:/…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/22 4:13:47

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/22 1:32:34

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…