当前位置: 首页 > article >正文

用队列实现栈(C语言详解)——从错误思路到本质理解(结尾全代码)

目录一、问题本质二、整体结构设计三、两种核心方法非常关键一、方法一push时调整搬运到空队列二、方法二pop时调整你的方法三、两种方法本质对比重点四、正确思路关键转折五、核心实现六、执行过程有图有真相七、参数传递关键细节八、为什么不用全局变量九、为什么不用 Queue*十、内存释放高频考点十三、进阶思考一、问题本质题目要求«使用队列FIFO实现栈LIFO»---核心矛盾队列先进先出FIFO栈后进先出LIFO 关键点«❗不是“怎么存数据”而是“怎么控制顺序”»---二、整体结构设计typedef struct { Queue q1; Queue q2; } MyStack;---内存结构必须理解MyStack├──q1一个队列│ ├── phead → 节点 → 节点 → ...│ ├── ptail│ └── size└── q2另一个队列├── phead → 节点 → ...├── ptail└── size 每个队列本质是一个链表---三、两种核心方法非常关键在用队列实现栈时本质都是«❗通过“搬运元素”来改变顺序从而模拟 LIFO»但策略分为两种---一、方法一push时调整搬运到空队列核心思路push 时新元素先进空队列再把旧元素全部搬过来---执行过程示意原队列1 2push(3)步骤q2: 3q1: 1 2↓q2: 3 1 2↓交换 q1 和 q2最终q1: 3 1 2---特点操作| 复杂度push| O(n)pop| O(1)top| O(1)---本质理解在 push 时就把顺序排好保证队头永远是栈顶---二、方法二pop时调整你的方法核心思路pop 时把前 n-1 个元素搬到另一个队列剩下最后一个栈顶---执行过程示意q1: 1 2 3q2: 空pop()↓q1: 3q2: 1 2↓删除 3---特点操作| 复杂度push| O(1)pop| O(n)top| O(1)---本质理解平时不调整在需要取栈顶时才“临时整理顺序”---三、两种方法本质对比重点维度| 方法一push调整| 方法二pop调整调整时机| push 时| pop 时思维方式| 提前整理| 延迟处理push| 慢O(n)| 快O(1)pop| 快O(1)| 慢O(n)---四、统一本质最重要这两种方法本质是一样的都是在“移动元素顺序”只是选择了不同的时机------六、进阶还有第三种一个队列push 后旋转队列把新元素转到最前面四、正确思路关键转折 push简单pop时调整顺序就是向非空的队列push数据pop是借助另一个空链表转换一下前size-1个最后一个就是栈顶进行pop操作即可---五、核心实现---1️⃣ push入栈void myStackPush(MyStack* obj, int x) { if(!QueueEmpty((obj-q1))) { QueuePush((obj-q1),x); } else{ QueuePush((obj-q2),x); } } 只负责存---2️⃣ pop出栈——核心int myStackPop(MyStack* obj) { Queue* NoEmpty (obj-q1), *Empty (obj-q2); if(QueueEmpty((obj-q1))) { NoEmpty (obj-q2); Empty (obj-q1); }// 搬运前 n-1 个元素while(QueueSize(NoEmpty) 1) { QueuePush(Empty, QueueFront(NoEmpty)); QueuePop(NoEmpty); }// 剩下的就是栈顶int top QueueFront(NoEmpty);QueuePop(NoEmpty);return top;}--- 本质每次 pop把前 n-1 个搬走最后一个就是栈顶---3️⃣ top取栈顶int myStackTop(MyStack* obj) { if(!QueueEmpty((obj-q1))) return QueueBack((obj-q1)); else return QueueBack((obj-q2)); }---4️⃣ 判空bool myStackEmpty(MyStack* obj) { return QueueEmpty((obj-q1)) QueueEmpty((obj-q2)); } ---六、执行过程有图有真相---初始状态q1: 1 → 2 → 3q2: 空---pop过程① 搬运前两个q1: 1 → 2 → 3q2: 空↓q1: 3q2: 1 → 2---② 删除最后一个pop 3--- 成功实现“后进先出”---七、参数传递关键细节---✅ 必须传指针QueuePush(obj-q1, x);---❌ 错误写法QueuePush(obj-q1, x); 只会修改副本原数据不变---八、为什么不用全局变量如果写成Queue q1;Queue q2;--- 问题- ❌ 多个栈共享数据- ❌ 数据混乱- ❌ 不符合接口设计--- 正确MyStack 内部管理自己的队列---九、为什么不用 Queue*Queue* q1;Queue* q2;---❌ 问题- 需要额外 malloc- 需要多次 free- 容易内存泄漏--- 当前场景Queue 很小 不需要共享 ✔ 用值更简单---十、内存释放高频考点---❌ 错误free(obj);---✔ 正确void myStackFree(MyStack* obj) { QueueDestroy((obj-q1)); QueueDestroy((obj-q2)); free(obj); }--- 原理链表节点是多次 malloc必须逐个释放---十一、复杂度分析操作| 时间复杂度push| O(1)pop| O(n)top| O(1)---十二、这一题真正考察的能力--- 1. 数据结构本质«❗结构 ≠ 用法而是行为控制»--- 2. 顺序控制能力关键不是存数据而是调整顺序--- 3. 内存管理谁申请 → 谁释放--- 4. 封装设计MyStack 管理 QueueQueue 管理节点---十三、进阶思考 有没有办法push O(n)pop O(1) 或者只用一个队列实现栈下一篇可以写单队列“旋转法”---✅ 总结«这题的本质不是“用队列”而是❗在受限结构下构造另一种行为LIFO»---typedef int QDataType; typedef struct QueueNode { struct QueueNode* next; QDataType val; }QNode; typedef struct Queue { QNode* phead; QNode* ptail; int size; }Queue; void QueueInit(Queue* pq) { assert(pq); pq-phead NULL; pq-ptail NULL; pq-size 0; } void QueueDestroy(Queue* pq) { assert(pq); QNode* cur pq-phead; while (cur) { QNode* next cur-next; free(cur); cur next; } pq-phead pq-ptail NULL; pq-size 0; } // 队尾插入 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode (QNode*)malloc(sizeof(QNode)); if (newnode NULL) { perror(malloc fail); return; } newnode-next NULL; newnode-val x; if (pq-ptail NULL) { pq-phead pq-ptail newnode; } else { pq-ptail-next newnode; pq-ptail newnode; } pq-size; } // 队头删除 void QueuePop(Queue* pq) { assert(pq); assert(pq-size ! 0); /*QNode* next pq-phead-next; free(pq-phead); pq-phead next; if (pq-phead NULL) pq-ptail NULL;*/ // 一个节点 if (pq-phead-next NULL) { free(pq-phead); pq-phead pq-ptail NULL; } else // 多个节点 { QNode* next pq-phead-next; free(pq-phead); pq-phead next; } pq-size--; } QDataType QueueFront(Queue* pq) { assert(pq); assert(pq-phead); return pq-phead-val; } QDataType QueueBack(Queue* pq) { assert(pq); assert(pq-ptail); return pq-ptail-val; } int QueueSize(Queue* pq) { assert(pq); return pq-size; } bool QueueEmpty(Queue* pq) { assert(pq); return pq-size 0; } typedef struct { Queue q1; Queue q2; } MyStack; MyStack* myStackCreate() { MyStack* pst (MyStack*)malloc(sizeof(MyStack)); QueueInit((pst-q1)); QueueInit((pst-q2)); return pst; } void myStackPush(MyStack* obj, int x) { assert(obj); if(!QueueEmpty((obj-q1))) { QueuePush((obj-q1),x); } else{ QueuePush((obj-q2),x); } } int myStackPop(MyStack* obj) { //将前size-1个导入空队列 在pop //假设法找到非空队列、 Queue* NoEmpty (obj-q1), *Empty (obj-q2); if(QueueEmpty((obj-q1))) { NoEmpty (obj-q2); Empty (obj-q1); } while(QueueSize(NoEmpty) 1) { QueuePush(Empty,QueueFront(NoEmpty)); QueuePop(NoEmpty); } //此时NoEmpty就剩下1个在删除 int top QueueFront(NoEmpty); QueuePop(NoEmpty); return top; } int myStackTop(MyStack* obj) { if(!QueueEmpty((obj-q1))) { return QueueBack((obj-q1)); } else { return QueueBack((obj-q2)); } } bool myStackEmpty(MyStack* obj) { return QueueEmpty((obj-q1)) QueueEmpty((obj-q2)); } void myStackFree(MyStack* obj) { QueueDestroy((obj-q1)); QueueDestroy((obj-q2)); free(obj); } /** * Your MyStack struct will be instantiated and called as such: * MyStack* obj myStackCreate(); * myStackPush(obj, x); * int param_2 myStackPop(obj); * int param_3 myStackTop(obj); * bool param_4 myStackEmpty(obj); * myStackFree(obj); */

相关文章:

用队列实现栈(C语言详解)——从错误思路到本质理解(结尾全代码)

目录 一、问题本质 二、整体结构设计 三、两种核心方法(非常关键) 一、方法一:push时调整(搬运到空队列) 二、方法二:pop时调整(你的方法) 三、两种方法本质对比(重…...

简单理解NAT(网络地址转换)模式和桥接模式

目录桥接模式NetworkAddressTranslation网络地址转换模式总结桥接模式 桥接模式下 物理机创建出来的虚拟机和物理机属于同一个网段 虚拟机占用实际IP 问题一:C类网最多分配254个IP地址 IP可能不够用(容易造成IP冲突) 问题二:由于物理机和虚拟机属于同一网段 彼此之间可以直接相…...

从入门到实战:Harbor 私有镜像仓库完全使用指南

从入门到实战:Harbor 私有镜像仓库完全使用指南 前言 在容器化盛行的今天,Docker 镜像的管理与分发变得至关重要。Harbor 作为一个开源的云原生容器镜像仓库,不仅提供了安全的镜像存储和访问控制,还集成了漏洞扫描、内容签名和复…...

Nacos Docker 安装文档 (MacBook Pro M2)

文档信息 适用环境: MacBook Pro with Apple Silicon (M2芯片) Nacos版本: v2.4.0-slim (支持ARM64架构) 数据库: MySQL 5.7/8.0 一、环境准备 1.1 检查Docker环境 # 检查Docker是否安装 docker --version# 检查Docker运行状态 docker info# 确认支持ARM64架构 docker inf…...

实战指南:基于OpenCV与RTSP协议,轻松接入海康萤石网络摄像头视频流

1. 环境准备与设备连接 第一次接触海康萤石摄像头时,我也被那一堆网线和参数搞得头晕。后来发现只要理清思路,整个过程就像拼乐高一样简单。以CS-C3S-52WEFR这款经典机型为例,我们需要准备以下硬件: 带LAN口的路由器(我…...

Asian Beauty Z-Image Turbo 模型压缩与加速:在边缘设备部署的探索

Asian Beauty Z-Image Turbo 模型压缩与加速:在边缘设备部署的探索 最近几年,AI图像生成模型的发展速度,快得有点让人跟不上。从最初的模糊涂鸦,到现在能生成以假乱真的高清人像、风景,效果确实惊艳。但不知道你有没有…...

ZXPInstaller:跨平台Adobe插件安装利器,让创意工作流无缝衔接

ZXPInstaller:跨平台Adobe插件安装利器,让创意工作流无缝衔接 【免费下载链接】ZXPInstaller Open Source ZXP Installer for Adobe Extensions 项目地址: https://gitcode.com/gh_mirrors/zx/ZXPInstaller 在数字创意领域,Adobe系列软…...

Flask Session 安全攻防实战:从密钥泄露到防御加固

1. Flask Session 安全威胁全景扫描 Flask 的客户端 Session 机制就像把家门钥匙藏在门口的垫子下面——虽然方便了自己,但也给小偷留了机会。我见过太多开发者直接照搬官方文档的示例代码,结果把整个系统的安全防线变成了纸糊的城墙。先带大家看看攻击者…...

解决6818开发板 syntax error: unexpected word的问题

首先确定ubantu成功安装了交叉编译工具链。假设需要编译的文件是1.c,需要生成test1文件。在ubantu进行编译:arm-linux-gcc 1.c -o test1然后在开发板上运行:./test1如果开发板出现了syntax error: unexpected word,有可能是使用了…...

色彩管理与显示优化:让你的NVIDIA显卡呈现真实色彩

色彩管理与显示优化:让你的NVIDIA显卡呈现真实色彩 【免费下载链接】novideo_srgb Calibrate monitors to sRGB or other color spaces on NVIDIA GPUs, based on EDID data or ICC profiles 项目地址: https://gitcode.com/gh_mirrors/no/novideo_srgb 当你…...

internlm2-chat-1.8b效果实测:中文成语接龙+文化背景解释趣味能力展示

internlm2-chat-1.8b效果实测:中文成语接龙文化背景解释趣味能力展示 最近在玩一个挺有意思的AI模型——书生浦语团队开源的internlm2-chat-1.8b。这个模型虽然参数不大,只有18亿,但听说在中文理解和对话上表现不错。我把它部署在Ollama上&a…...

从零开始:在Qt项目中优雅地使用系统图标(QIcon::fromTheme详解)

从零开始:在Qt项目中优雅地使用系统图标(QIcon::fromTheme详解) 在桌面应用开发中,图标是用户界面不可或缺的元素。它们不仅美化界面,还能通过视觉符号快速传达功能意图。对于Qt开发者而言,QIcon::fromThe…...

【实战】Godot VSCode联调:从零搭建高效脚本工作流

1. 为什么需要Godot与VSCode联调? 作为一个从Unity转战Godot的老鸟,我最初也被Godot内置编辑器折磨得不轻。虽然内置编辑器对新手友好,但当你需要处理复杂项目时,代码补全慢、调试功能弱、界面拥挤等问题就会暴露无遗。特别是开发…...

PDF文档处理新选择:MinerU 2.5-1.2B镜像快速部署与使用指南

PDF文档处理新选择:MinerU 2.5-1.2B镜像快速部署与使用指南 1. 引言:为什么选择MinerU处理PDF文档 在日常工作和研究中,我们经常需要从PDF文档中提取内容。传统的PDF转文本工具往往无法正确处理复杂排版,比如学术论文中的多栏布…...

tomcat安装后忘记放在哪里以及怎么打开tomcat

sudo find / -name apache-tomcat-*.tar.gzsu -find ./ -name ^tomcatcd /export/server/tomcatcd bin./startup.sh最后显示Tomcat started.说明开启成功netstat -anp | grep 8080 查看8080端口占用情况最后浏览器上 http://localhost:8080就能连接上...

网盘直链解析技术白皮书:突破下载限制的高效解决方案

网盘直链解析技术白皮书:突破下载限制的高效解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改(改自6.1.4版本) ,自用,去推广&#…...

零基础玩转Qwen2.5-7B-Instruct:手把手教你用chainlit搭建智能对话前端

零基础玩转Qwen2.5-7B-Instruct:手把手教你用chainlit搭建智能对话前端 1. 环境准备与快速部署 1.1 系统要求 操作系统:Linux (推荐Ubuntu 20.04)Python版本:3.8GPU:NVIDIA显卡(显存≥16GB)内存:≥32GB 1.2 安装依…...

CLI-Anything 原理与实践:MCP 之外的另一种 Agent 工具接入方式

CLI-Anything 项目解析:它会替代 MCP 吗? 当大家都在讨论 AI Agent、MCP、Tool Use 的时候,一个更底层的问题其实越来越明显:AI 很会推理,却并不擅长稳定地使用真实世界的软件。 它会写代码,会拆任务,会调用 API,但一旦面对复杂桌面软件、老项目、没有完整接口的应用,…...

YOLOv11优化全景图:从模块革新到部署实战,200+顶会方案融合与工程化指南

1. YOLOv11核心模块革新全景图 YOLOv11作为目标检测领域的最新力作,其架构创新主要体现在六大核心模块的协同优化上。我在实际项目中发现,理解这些模块的相互作用比单纯堆砌改进方法更重要。Backbone部分采用了混合卷积与注意力机制的设计,实…...

【统计检验】F检验与F分布

统计检验核心:F检验与F分布|原理推导Python可视化机器学习实战 F检验是统计学中用于比较方差、做方差分析(ANOVA)、检验回归方程显著性的核心方法,也是本科数理统计、研究生数据分析与机器学习特征选择的必学内容。一、…...

松下A6BE伺服电机增益调整与振动抑制:如何通过自动调整功能提升系统稳定性

松下A6BE伺服电机增益调整与振动抑制实战指南 在工业自动化领域,伺服系统的稳定性直接影响着设备运行效率与产品质量。作为松下MINAS A6系列的核心产品,A6BE伺服电机凭借其实时自动调整和适应滤波器两大创新功能,为工程师提供了解决系统振动问…...

利用SmolVLA自动化生成技术文档:UML图转文字说明

利用SmolVLA自动化生成技术文档:UML图转文字说明 每次项目评审,最头疼的是什么?对我来说,除了改不完的Bug,就是写不完的技术文档。特别是设计文档,对着画好的UML图,要把每个类、每个方法、每个…...

Janus-Pro-7B在工业物联网(IIoT)的应用:设备仪表盘图像智能诊断

Janus-Pro-7B在工业物联网(IIoT)的应用:设备仪表盘图像智能诊断 想象一下,在一个大型工厂的车间里,成百上千台设备正在轰鸣运转。每台设备上都有仪表盘、指示灯和显示屏,显示着压力、温度、转速等关键数据…...

从零开始掌握HTTP协议:全面详解1.0、1.1和2.0

HTTP协议概述1. 回顾 Http1.x协议 Http1.0协议 请求响应的模式 短连接协议(无状态协议) 传输数据文本结构 单工 无法实现服务端推送 变相实现推动(客户端轮训的方式) Http1.1协议 请求响应的模式 有限的长连接 …...

SeqGPT-560M多场景落地指南:新闻分类、金融抽取、政务摘要一体化方案

SeqGPT-560M多场景落地指南:新闻分类、金融抽取、政务摘要一体化方案 1. 模型介绍:零样本理解新选择 SeqGPT-560M是阿里达摩院推出的零样本文本理解模型,无需训练即可完成文本分类和信息抽取任务。这个模型最大的特点就是"开箱即用&qu…...

基于异步电机的光伏储能三相并网微电网仿真模型附Simulink仿真

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室🍊个人信条:格物致知,完整Matlab代码及仿真咨询…...

Apex Legends智能压枪系统深度解析:3大核心技术实现与多分辨率适配工程实践

Apex Legends智能压枪系统深度解析:3大核心技术实现与多分辨率适配工程实践 【免费下载链接】Apex-NoRecoil-2021 Scripts to reduce recoil for Apex Legends. (auto weapon detection, support multiple resolutions) 项目地址: https://gitcode.com/gh_mirrors…...

如何用代码画图?揭秘Mermaid Live Editor的终极可视化创作体验

如何用代码画图?揭秘Mermaid Live Editor的终极可视化创作体验 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-liv…...

5步搞定!用FUTURE POLICE为爬取的播客/访谈录音添加毫秒级精准字幕

5步搞定!用FUTURE POLICE为爬取的播客/访谈录音添加毫秒级精准字幕 1. 引言:为什么需要精准字幕? 在内容创作和媒体制作领域,字幕同步问题一直是个痛点。传统字幕制作通常需要: 先通过语音识别生成文字稿人工反复听…...

Reloaded-II:让游戏模组管理不再复杂的跨平台解决方案

Reloaded-II:让游戏模组管理不再复杂的跨平台解决方案 【免费下载链接】Reloaded-II Next Generation Universal .NET Core Powered Mod Loader compatible with anything X86, X64. 项目地址: https://gitcode.com/gh_mirrors/re/Reloaded-II 在游戏模组开发…...