栈与队列:从原理到应用
文章目录1. 引言2. 栈Stack后进先出的线性表3. 队列Queue先进先出的线性表4. 代码实现示例栈的实现代码5. 栈与队列的对比总结6. 总结与学习建议1. 引言栈和队列是计算机科学中最基础、也最常用的两种数据结构。它们都属于线性表但通过“限制插入和删除的位置”形成了完全不同的操作规则栈是后进先出LIFO队列是先进先出FIFO。理解栈和队列之所以重要主要有三个原因它们是理解程序运行逻辑的基础。函数调用、递归、表达式求值、编辑器撤销、浏览器后退等日常功能背后都依赖栈而任务调度、消息队列、广度优先搜索等场景则离不开队列。它们是很多算法和高级数据结构的起点。深度优先搜索与栈、广度优先搜索与队列之间有着天然联系单调栈、循环队列、双端队列、优先队列等也都是从栈和队列的基础上延伸出来的。它们是面试与工程实践中的高频内容。很多经典面试题都围绕栈和队列展开真正理解它们的存储方式、操作特性和复杂度分析也是后续学习树、图等复杂结构的重要基础。本文将围绕栈和队列的定义、实现、应用场景、代码示例以及常见面试题展开帮助读者从原理到实践系统掌握这两种数据结构。2. 栈Stack后进先出的线性表栈的定义与核心特征后进先出LIFO, Last In First Out栈的基本操作入栈push、出栈pop、取栈顶peek/top、判空isEmpty栈的两种实现方式顺序栈基于数组链式栈基于链表栈可以用链表来实现但是因为进栈和出栈对于数组和链表来说都很简单而数组占用空间更小所以一般使用数组来充当栈的底层数据存储的角色。3. 队列Queue先进先出的线性表队列的定义与核心特征先进先出FIFO, First In First Out队列的基本操作入队enqueue、出队dequeue、取队首front、判空isEmpty队列的抽象数据类型ADT描述队列的两种实现方式顺序队列基于数组链式队列基于链表因为链表会用到头部删除头部插入所以用链表来表示。4. 代码实现示例栈的实现代码栈的结构体和数据类型的确定typedefintSTDataType;typedefstructstack{STDataType*arr;//等效为size;inttop;intcapacity;}ST;栈的实现代码voidSTInit(ST*ps){assert(ps);ps-arrNULL;ps-topps-capacity0;}voidSTPush(ST*ps,STDataType x){assert(ps);if(ps-capacityps-top){//使用问好表达式加括号intnewcapacity(ps-capacity0?4:ps-capacity*2);//用realloc新开STDataType*tmp(STDataType*)realloc(ps-arr,sizeof(STDataType)*newcapacity);if(!tmp){perror(malloc failed:);exit(1);}ps-arrtmp;//capacity也要改ps-capacitynewcapacity;}//插入数据后记得让topps-arr[ps-top]x;}//检查栈是否为空boolSTEmpty(ST*ps){assert(ps);//只需要关注top的值就行returnps-top0;}STDataTypeSTPop(ST*ps){assert(!STEmpty(ps));//删除只需要让有效数据减一ps-top--;returnps-arr[ps-top];}//返回栈顶处的值STDataTypeSTTop(ST*ps){assert(!STEmpty(ps));//注意这里是返回top - 1的值returnps-arr[ps-top-1];}voidSTDestroy(ST*ps){assert(ps);//这里需要检查一下数组是不是空的freeNULL会导致程序崩溃if(ps-arr)free(ps-arr) ps-arrNULL;ps-topps-capacity0;}intSTSize(ST*ps){assert(ps);returnps-top;}队列结构体和数据类型的确定这里需要两个结构体一个结构体用于创建队列另一个用于创建队列的节点typedefintQDatatype;typedefstructQueueNode{QDatatype data;structQueueNode*next;}QN;typedefstructQueue{QN*phead;QN*ptail;//为了快速访问大小intsize;}qu;队列的实现代码voidQueueInit(qu*pq){//注意有解引用就有断言assert(pq);pq-pheadpq-ptailNULL;pq-size0;}voidQueueDestroy(qu*pq){assert(pq);QN*pcurpq-phead;while(pcur){QN*nextpcur-next;free(pcur);pcurnext;}pq-pheadpq-ptailNULL;pq-size0;}intQueueSize(qu*pq){assert(pq);returnpq-size;}//入队---队尾//注意想要在函数里创建新节点只能用内存函数voidQueuePush(qu*pq,QDatatype x){assert(pq);//这里注意检查mallocQN*Newnode(QN*)malloc(sizeof(QN));if(!Newnode){perror(malloc failed);exit(1);}Newnode-datax;Newnode-nextNULL;//这里需要特判一下如果头节点为空后面ptail会出现空指针解引用if(pq-pheadNULL){pq-pheadpq-ptailNewnode;}else{pq-ptail-nextNewnode;pq-ptailpq-ptail-next;}pq-size;}//和所以数据结构一样要删除数据之前要验查是否为空boolQueueEmpty(qu*pq){assert(pq);returnpq-ptailNULL;}//出队对头QDatatypeQueuePop(qu*pq){//删除数据都要判空assert(!QueueEmpty(pq))//这里需要保存出队数据QDatatype revpq-phead-data;//只有一个节点的时候要特判if(pq-pheadpq-ptail){free(pq-phead);pq-ptailpq-pheadNULL;}else{QN*nextpq-phead-next;free(pq-phead);pq-pheadnext;}//删除之后size--pq-size--;returnrev;}QDatatypeQueueFront(qu*pq){//注意这里要判空取数据一定不能为空assert(!QueueEmpty(pq));returnpq-phead-data;}QDatatypeQueueBack(qu*pq){assert(!QueueEmpty(pq));returnpq-ptail-data;}5. 栈与队列的对比总结栈和队列本质上都是“操作受限的线性表”都是在一组相同类型元素之间建立先后顺序。它们最主要的区别在于插入和删除发生的位置不同由此形成了截然不同的访问规则。从操作规则上看栈遵循LIFOLast In First Out后进先出所有插入和删除都只发生在同一端也就是“栈顶”。因此最后入栈的元素会最先被取出。队列则遵循FIFOFirst In First Out先进先出插入发生在队尾删除发生在队首最先入队的元素最先出队。从实现方式上看两者都可以基于数组或链表实现。栈的入栈和出栈都只在栈顶进行因此无论使用数组还是链表操作都比较简单由于数组在空间上更紧凑实际中更常使用数组作为栈的底层存储。队列则需要在队尾插入、在队首删除使用数组实现顺序队列时容易出现“假溢出”问题因此实际工程中常采用循环队列而使用链表实现队列时需要通过维护队首和队尾指针来保证两端操作都足够高效。在选择数据结构时可以按照以下思路判断如果问题具有“后进先出”的特征例如函数调用、撤销操作、括号匹配、表达式求值等应优先考虑栈。如果问题需要按照“先进先出”的顺序处理例如任务调度、消息队列、广度优先搜索、缓冲区等应优先考虑队列。简单来说栈解决的是“最近发生的事先处理”的问题而队列解决的是“最早发生的事先处理”的问题。理解两者的限制条件与操作特性是进一步学习双端队列、优先队列以及相关算法的基础。6. 总结与学习建议栈和队列是数据结构学习中绕不开的两个基础结构它们都属于“操作受限的线性表”核心差别只在于插入和删除发生的位置不同栈只能在栈顶进出遵循后进先出LIFO队列在队尾插入、在队首删除遵循先进先出FIFO。在实现上两者都可以基于数组或链表完成。栈由于只在一端操作实现相对简单实际中更常用数组来充当底层存储队列则因为需要维护两端操作使用数组时要注意“假溢出”问题工程中常采用循环队列或者通过链表维护队首、队尾指针来保证高效。学习这两个结构时可以重点关注几个易错点入栈、出栈前要留意栈是否已满或已空循环队列要理清取模运算以及判空与判满条件的区别链表实现时要注意指针更新的先后顺序避免断链或重复释放。后续学习中可以把栈和队列当作进一步理解递归、深度优先搜索、广度优先搜索以及单调栈、优先队列等高级内容的基础。多做“用栈模拟递归”“用队列实现广度优先搜索”等练习能够帮助更快建立起对数据结构的直觉。

相关新闻

# 京东客服离线自动回复怎么设置?叮当小宝CS补上夜间与高峰的接待缺口

# 京东客服离线自动回复怎么设置?叮当小宝CS补上夜间与高峰的接待缺口

京东的考核里,回复速度和应答率都算分。客服下班、午休或者大促期间排队太长时,买家的咨询不能一直挂着——离线自动回复就是兜底的那一道。这篇把入口、生效范围和常见的「配了但没用」讲清楚,再给一套补位做法。## 先分清两个入口&#xff…

2026/10/14 3:25:35 阅读更多 →
MySQL 从入门到实战(03):数据类型与建表规范

MySQL 从入门到实战(03):数据类型与建表规范

数据类型与建表规范 本篇所有 SQL 在本机 MySQL 8.0.46 实测。 核心问题:为什么金额要用 DECIMAL 而不是 FLOAT?VARCHAR(255) 是不是越大越好? 一、一个真实的踩坑:浮点数存金额 先看实测结果: CREATE TABLE demo.t_money_bad (id INT PRIMARY KEY AUTO_INCREMENT,amoun…

2026/10/14 3:25:35 阅读更多 →
COBOL报表开发实战:物理布局、文件绑定与状态机生命周期

COBOL报表开发实战:物理布局、文件绑定与状态机生命周期

简介:本资源是一份面向COBOL初学者与金融/政务系统维护人员的报表开发实践指南,聚焦COBOL环境下的结构化报表生成全流程。内容以真实可运行的rpt001程序为核心,完整呈现ID、Environment、Data(含File Section与Working-Storage&am…

2026/10/14 3:25:35 阅读更多 →

最新新闻

办公设备管理系统OAMS源码实战:从台账混乱到扫码即用

办公设备管理系统OAMS源码实战:从台账混乱到扫码即用

简介:办公设备管理系统OAMS是一套面向企事业单位设备管理员与信息化开发者的全生命周期管理解决方案,覆盖采购、入库、领用、维修、报废等核心环节,适合需要落地资产台账、审批流程与统计报表的Java Web项目学习与二次开发。资源包共451个文件…

2026/10/14 4:00:41 阅读更多 →
SpringBoot2+Vue3流浪宠物管理系统:前后端分离架构实战解析

SpringBoot2+Vue3流浪宠物管理系统:前后端分离架构实战解析

1. 这个系统解决的是什么问题:流浪宠物救助的数字化盲区说实话,市面上打着"宠物管理系统"旗号的项目源码并不少,但真正能落地到流浪动物救助场景的却不多。大部分所谓管理系统要么是单纯的前端页面堆砌,要么后端只做了简…

2026/10/14 4:00:41 阅读更多 →
Matlab实现CNN-GRU多特征分类预测:从数据准备到模型落地

Matlab实现CNN-GRU多特征分类预测:从数据准备到模型落地

涉及到用Matlab做时序或者多维特征数据的分类预测时,CNN-GRU这个组合近年来出镜率非常高。一方面卷积结构擅长局部特征提取,另一方面GRU门控循环单元对序列依赖关系的建模能力又比普通前馈网络强很多,两个搭在一起后,既能处理多维…

2026/10/14 4:00:41 阅读更多 →
Claude Code + git worktree 多分支并行开发实战指南

Claude Code + git worktree 多分支并行开发实战指南

最近半年我一直在重度使用 Claude Code 做日常开发,手头同时维护好几个功能分支是常有的事。一开始我还是老一套:开一个终端窗口,在一个工作目录里反复git checkout切换分支,切来切去不仅脑子乱,更麻烦的是 Claude Cod…

2026/10/14 4:00:41 阅读更多 →
中小团队 CI/CD 工具选哪个:2026 年主流平台对比与 Gitee 方案解析

中小团队 CI/CD 工具选哪个:2026 年主流平台对比与 Gitee 方案解析

中小团队选择 CI/CD 工具的核心结论是:没有"最好"的工具,只有匹配团队规模、技术栈与合规要求的方案;据 JetBrains 2025 年开发者生态系统报告,GitHub Actions 以 33% 采用率领跑,Jenkins 以 28% 紧随其后&a…

2026/10/14 4:00:41 阅读更多 →
从零构建每日晨报:信息过滤系统的设计与实现

从零构建每日晨报:信息过滤系统的设计与实现

1. 一份“每日晨报”到底在解决什么问题每天早上七点半,我习惯性打开自己维护的一个小工具,屏幕上会弹出一份排版干净的简报:昨天圈子里发生了什么、有哪些值得点进去看的链接、今天有什么值得留意的节点。这份东西我管它叫“每日晨报”&…

2026/10/14 3:59:41 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →