一篇文章带你了解——栈和队列
目录栈1、栈的基本概念2、栈的实现方式——数组存储结构初始化销毁入栈取出栈顶元素获取栈顶元素判空获取栈的长度3、实现方式——链表存储结构初始化销毁入栈出栈获取栈顶元素获取栈中有效元素个数判空队列基本概念队列的存储结构初始化销毁判空队列长获取头的元素入队列出队列栈1、栈的基本概念栈栈(stack)是限定仅在⼀端进⾏插⼊或删除操作的线性表。栈顶top能插入和删除的一端栈顶(bottom)不能插入和删除的一端出栈删除数据在栈顶入栈放入数据在栈顶——也叫压栈/入栈/进栈空栈没用任何元素栈也被称为后进先出的顺序表Last In First Out简称LIFO结构2、栈的实现方式——数组使用结构选择数组因为栈是“尾部操作”最频繁的数据结构后进先出而数组在尾部操作入栈/出栈的时间复杂度是 O(1)且内存连续、缓存利用率极高所以用数组是最自然、最高效的选择。基本操作void STInit(ST* st);//初始化void STDestroy(ST* st);//销毁void STPush(ST* st,STDataType x);//入栈void STPop(ST* st);//出栈STDataType STTop(ST* st);//获取栈顶元素bool STEmpty(ST* st);//判空int STSize(ST* st);//取长度存储结构typedef int STDataType; typedef struct Stack { STDataType* a;//存储数组 int top;//栈顶的下一位 int capacity;//容量 }ST;注意这里的top到底是指向栈顶元素还是栈顶的下一位如果指向栈顶元素那么top的初始化就要是-1如果是栈顶元素的下一位就是0。因为这里要思考一个问题 就是当top0的时候数组是否有元素如果top0的时候没用那么我们就要让top指向栈顶元素的下一位。下面的top指向的是栈顶元素的下一位。初始化void STInit(ST* st) { assert(st); st-a NULL; st-top 0; st-capacity 0; }销毁void STDestroy(ST* st) { assert(st); free(st-a); st-a NULL; st-capacity 0; st-top 0; }入栈void STPush(ST* st, STDataType x) { assert(st); if (st-top st-capacity) { int newcapacity st-capacity 0 ? 4 : st-capacity * 2; STDataType* tmp (STDataType*)realloc(st-a, newcapacity*sizeof(STDataType)); if (tmpNULL) { perror(realloc fail); return; } st-atmp; st-capacity newcapacity; } st-a[st-top] x; st-top; }取出栈顶元素void STPop(ST* st) { assert(st); assert(st-top0); st-top--; }获取栈顶元素STDataType STTop(ST* st) { assert(st); assert(st-top 0); return st-a[st-top-1]; }判空bool STEmpty(ST* st) { assert(st); return st-top 0; }获取栈的长度int STSize(ST* st) { assert(st); return st-top; }3、实现方式——链表链式栈的结构可以选择单链表也可以选择双向链表但是需要知道的是如果选择单链表要用头当作栈顶因为栈的特点就是在栈顶取数据和出数据单链表在头节点取出和放入数据的时间复杂度都是O1尾节点还要遍历找尾时间复杂度是O(N)。当然也可以使用双向链表而且无论是用头还是尾做栈顶时间复杂度都是O1但是建议还是选择单链表因为单链表相比双向链表节省空间因此使用单链表。在使用单链表的时候可以不使用哨兵位头结点也可用这里我不用因为哨兵位头结点并没有给头删和头插带来遍历所以不用也可以节省一个节点的空间。存储结构typedef int LSDataType; typedef struct LinkStackNode { struct LinkStackNode* Next; LSDataType data; }LSNode; typedef struct { LSNode* phead; int size; }LinkStack;这里定义了两个结构体对应了链表的节点和栈的管理结构他们的作用是不一样的可以把他们看作一个火车的车厢和火车头其中LinkStack是用来控制链表的起点和长度LSNode就是车厢的行李他们就构成了一个栈。初始化// 初始化链式栈s void LinkStackInit(LinkStack* s) { assert(s); s-phead NULL; s-size 0; }初始化的对象是LinkStack而不是LSNode因为要先有火车头LSNode等到入栈的时候才初始化因为入栈才开始创造节点。销毁// 销毁链式栈s void LinkStackDestroy(LinkStack* s) { assert(s); LSNode* cur s-phead; while (cur) { LSNode* nextNode cur-Next; free(cur); cur nextNode; } s-phead NULL; s-size 0; }入栈void LinkStackPush(LinkStack* s, LSDataType x) { assert(s); LSNode* newNode (LSNode*)malloc(sizeof(LSNode));//这里就要开始利用LSNode if (newNode NULL) { perror(malloc fail); return; } newNode-data x; newNode-Next s-phead; s-phead newNode; s-size; }出栈// 出栈并返回栈顶元素 LSDataType LinkStackPop(LinkStack* s) { assert(s); assert(s-size0); LSDataType ret s-phead-data; LSNode* nextNode s-phead-Next; free(s-phead); s-phead nextNode; s-size--; return ret; }获取栈顶元素// 获取栈顶元素 LSDataType LinkStackTop(LinkStack* s) { assert(s); assert(s-size 0); return s-phead-data; }获取栈中有效元素个数int LinkStackSize(LinkStack* s) { assert(s); return s-size; }判空bool LinkStackEmpty(LinkStack* s) { assert(s); return s-size 0; }队列基本概念队列只允许在一端进行插入数据操作在另一端进行删除数据操作的特殊线性表队列具有先进先出 FIFO(First In First Out)入队列进行插入操作的一端称为队尾出队列进行删除操作的一端称为队头队列的存储结构队列的链式存储我们可以选⽤单链表结构也可以选⽤双向链表结构。他们⼊队对应着在表尾插 ⼊出队对应着在表头删除。当然我们完全没必要选择双向链表因为单链表就可以⾼效实现还 省空间⼀些。双向链表没有优势每个结点还要多存储⼀个前驱指针使⽤它纯粹浪费了。typedef int QDataType; typedef struct QueueLinkNode { QDataType data; struct QueueLinkNode* Next; }QNode; typedef struct { QNode* Phead; QNode* Ptail; int size; }LinkQueue;//和上面所说是车厢不过要多一个Ptail方便尾插这里和上面的链式的栈实现类似定义两个结构体一个是节点的结构一个是栈的管理结构因为队列还要考虑队尾插入队尾插入记录的时候方便直接找到最后一个。初始化void QueueInit(LinkQueue* q) { assert(q); q-Phead q-Ptail (QNode*)malloc(sizeof(QNode)); if (q-Phead NULL) { perror(malloc fail); return; } q-Phead-Next NULL; q-size 0; }这里选择带头结点的链表。销毁void QueueDestroy(LinkQueue* q) { assert(q); QNode* cur q-Phead; while (cur) { QNode* nextNode cur-Next; free(cur); cur nextNode; } q-Phead NULL; q-Ptail NULL;//都要置为NULL q-size 0; }判空bool QueueEmpty(LinkQueue* q) { assert(q); return q-size 0; }队列长int QueueSize(LinkQueue* q) { assert(q); return q-size; }获取头的元素QDataType QueueFront(LinkQueue* q) { assert(q); assert(q-size0); return q-Phead-Next-data; }入队列void EnQueue(LinkQueue* q, QDataType x) { assert(q); QNode* newNode (QNode*)malloc(sizeof(QNode)); if (newNode NULL) { perror(malloc fail); return; } newNode-data x; newNode-Next NULL; q-Ptail-Next newNode; q-Ptail newNode; q-size; }出队列QDataType DeQueue(LinkQueue* q) { assert(q); assert(q-size0); QNode* delNode q-Phead-Next; QDataType x delNode-data; q-Phead-Next delNode-Next; free(delNode); delNode NULL; q-size--; if (q-size 0) { q-Ptail q-Phead; } return x; }这里有一个特殊的情况删除最后一个节点的时候Ptail和Phead都要置为NULL避免野指针。

相关新闻

大模型微调完整分类

大模型微调完整分类

一、按训练目标 / 训练阶段(日常说的 SFT、偏好、强化微调)1. 普通微调(SFT 监督指令微调)就是你说的「普通微调」,最基础一环全称:Supervised Fine-Tuning 监督微调数据:标准问答、对话、领域标…

2026/9/29 6:31:30 阅读更多 →
AI日报:自动化采集与专业筛选的技术实践

AI日报:自动化采集与专业筛选的技术实践

1. 项目概述2026年6月30日AI日报是一个聚焦人工智能领域最新动态的资讯项目。作为长期跟踪AI技术发展的从业者,我每天都会整理行业内的突破性进展、重要论文发布、企业动态和开源项目更新。这个日报不同于普通的新闻聚合,而是经过专业筛选和深度解读的技…

2026/10/9 8:14:52 阅读更多 →
n8n运维实战:日志管理、监控与安全配置

n8n运维实战:日志管理、监控与安全配置

1. 为什么n8n实例需要完整的运维体系 当你在生产环境运行n8n工作流引擎时,会发现这个看似简单的工具背后隐藏着复杂的运维需求。我部署的第一个n8n实例就曾因为日志堆积导致磁盘爆满,整个服务突然崩溃。那次事故让我意识到:n8n作为自动化枢纽…

2026/10/3 0:21:20 阅读更多 →

最新新闻

深入排查npm报错:Cannot read properties of null (reading ‘matches‘)的完整指南

深入排查npm报错:Cannot read properties of null (reading ‘matches‘)的完整指南

先别急着清缓存重装,这个报错我前后折腾过好几次,每次原因都不一样。先花两分钟把错误本身看明白,后面能省一大堆时间。1. 报错拆解:这行错误到底在说什么1.1 错误信息的语法结构这行报错是典型的 JavaScript TypeError&#xff0…

2026/10/11 19:51:46 阅读更多 →
涉密项目投标前需要准备什么材料?

涉密项目投标前需要准备什么材料?

企业准备参与涉密项目投标,除了常规商务和技术材料,还须额外准备一套保密资质与管理类材料。很多企业因为材料不全或不符合要求,在资格审查阶段就被淘汰。先说结论:涉密项目投标前须准备五大类材料 —— 资质资格类、业绩证明类、…

2026/10/11 19:51:46 阅读更多 →
企业终端软件安装管控:堵住私自安装带来的内网安全缺口

企业终端软件安装管控:堵住私自安装带来的内网安全缺口

某制造企业 IT 运维曾遭遇一次典型内网安全事件:研发部门员工从第三方网站下载破解版仿真工具安装到办公电脑,安装包捆绑木马程序。该员工电脑拥有内网访问权限,木马入侵后横向扩散,短时间内多台终端被感染,业务系统出…

2026/10/11 19:51:46 阅读更多 →
lil-agents 多屏适配实战:Dock 自动隐藏时角色为何不消失?DockVisibility 深度解析

lil-agents 多屏适配实战:Dock 自动隐藏时角色为何不消失?DockVisibility 深度解析

【免费下载链接】lil-agents tiny AI companions that live on your macOS dock 项目地址: https://gitcode.com/gh_mirrors/li/lil-agents 点击查看 免费下载 lil-agents 是一款小巧的 macOS 应用,让 Bruce 和 Jazz 两个可爱的 AI 伴侣角色住在你的 Do…

2026/10/11 19:51:46 阅读更多 →
Amical听写历史与智能笔记完整指南:如何搜索、内联编辑并复用你的语音内容

Amical听写历史与智能笔记完整指南:如何搜索、内联编辑并复用你的语音内容

【免费下载链接】amical 🎙️ AI Dictation App - Open Source and Local-first ⚡ Type 3x faster, no keyboard needed. 🆓 Powered by open source models, works offline, fast and accurate. 项目地址: https://gitcode.com/gh_mirrors/…

2026/10/11 19:51:46 阅读更多 →
GitHub趋势周报:从Star数到构建链路的开发者情报作战图

GitHub趋势周报:从Star数到构建链路的开发者情报作战图

1. 这份周报不是“新闻简报”,而是一份开发者情报作战图 你点开GitHub Trending页面,刷到第40周的榜单——Top 25里有3个Rust项目、2个TypeScript驱动的CLI工具、1个用Zig重写的POSIX工具链,还有个叫 llm-local-runner 的本地大模型调度器…

2026/10/11 19:50:45 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练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/11 14:36:54 阅读更多 →