C++语言原理与实践(十三):stack、queue 和 priority_queue的介绍与使用
本篇目标学会stackqueue和priority_queue的接口使用引子stack、queue和priority_queue都属于容器适配器。它们不直接负责存储数据而是在其他容器的基础上封装出一组特定接口。#include stack #include queue #include vector #include functional using namespace std;一.stack1. 基本特点stack是栈遵循后进先出原则即 LIFOLast In First Out。只能直接访问栈顶元素入栈1 2 3 出栈3 2 1默认情况下stack使用deque作为底层容器。2. 常用接口接口功能时间复杂度stackT st构造一个空栈O(1)st.empty()判断栈是否为空O(1)st.size()返回元素个数O(1)st.top()访问栈顶元素O(1)st.push(x)将元素压入栈顶O(1)st.pop()删除栈顶元素O(1)基本使用#include iostream #include stack using namespace std; int main() { stackint st; st.push(10); st.push(20); st.push(30); while(!st.empty()) { coutst.top()endl; st.pop(); } return 0; }3. 使用特点pop()只删除不返回元素下面的写法是错误的int value st.pop(); // 错误正确写法int value st.top(); st.pop();访问栈顶前应先判断是否为空if (!st.empty()) { cout st.top() endl; }空栈调用top()或pop()会产生未定义行为。4.有效的括号网址20. 有效的括号 - 力扣LeetCode20. 有效的括号 - 给定一个只包括 (){}[] 的字符串 s 判断字符串是否有效。有效字符串需满足 1. 左括号必须用相同类型的右括号闭合。 2. 左括号必须以正确的顺序闭合。 3. 每个右括号都有一个对应的相同类型的左括号。 示例 1输入s ()输出true示例 2输入s ()[]{}输出true示例 3输入s (]输出false示例 4输入s ([])输出true示例 5输入s ([)]输出false 提示 * 1 s.length 104 * s 仅由括号 ()[]{} 组成https://leetcode.cn/problems/valid-parentheses/1.题意解释给定一个只包含(、)、[、]、{、}的字符串判断其中的括号是否正确匹配。例如()[]{} → true ([{}]) → true (] → false ([)] → false2.解题思路括号匹配需要满足左括号和右括号的类型必须相同。后出现的左括号必须先匹配。例如([{}])左括号进入顺序( → [ → {右括号出现后匹配顺序必须是} → ] → )这正好符合栈“后进先出”的特点。具体过程遇到左括号将其压入栈中。遇到右括号检查栈顶左括号是否与其匹配。如果栈为空说明右括号没有对应的左括号返回false。如果类型不匹配返回false。如果匹配就将栈顶左括号弹出。遍历结束后栈必须为空否则说明存在未匹配的左括号。3.示例分析以字符串([{}])为例当前字符操作栈中内容(左括号入栈([左括号入栈([{左括号入栈([{}与{匹配出栈([]与[匹配出栈()与(匹配出栈空遍历结束后栈为空因此括号匹配成功。两种失败情况1.右括号多())处理最后一个)时栈已经为空匹配失败。2.左括号多(()遍历结束后栈中还有一个(匹配失败。因此最后不能直接返回true必须返回return st.empty();4.代码实现class Solution { public: bool isValid(string s) { stackchar st; for (char ch : s) { // 遇到左括号直接入栈 if (ch ( || ch [ || ch {) { st.push(ch); } else { // 右括号过多 if (st.empty()) { return false; } char top st.top(); // 判断括号类型是否匹配 if ((ch ) top ! () || (ch ] top ! [) || (ch } top ! {)) { return false; } // 当前左右括号匹配 st.pop(); } } // 栈为空说明所有左括号都完成匹配 return st.empty(); } };二.queue1. 基本特点queue是队列遵循先进先出原则即 FIFOFirst In First Out。元素从队尾进入从队头离开入队1 2 3 出队1 2 3默认情况下queue使用deque作为底层容器。2. 常用接口接口功能时间复杂度queueT q构造一个空队列O(1)q.empty()判断队列是否为空O(1)q.size()返回元素个数O(1)q.front()访问队头元素O(1)q.back()访问队尾元素O(1)q.push(x)从队尾插入元素O(1)q.pop()删除队头元素O(1)基本使用#include iostream #include queue using namespace std; int main() { queueint q; q.push(10); q.push(20); q.push(30); while(!q.empty()) { coutq.front() ; q.pop(); } return 0; }3. 使用特点队头和队尾的作用不同q.front(); // 下一个将要出队的元素 q.back(); // 最后一个进入队列的元素pop()只删除队头不返回元素int value q.front(); q.pop();访问元素前要判断队列是否为空if (!q.empty()) { cout q.front() endl; }4.用队列实现栈225. 用队列实现栈 - 力扣LeetCode225. 用队列实现栈 - 请你仅使用两个队列实现一个后入先出LIFO的栈并支持普通栈的全部四种操作push、top、pop 和 empty。实现 MyStack 类 * void push(int x) 将元素 x 压入栈顶。 * int pop() 移除并返回栈顶元素。 * int top() 返回栈顶元素。 * boolean empty() 如果栈是空的返回 true 否则返回 false 。 注意 * 你只能使用队列的标准操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。 * 你所使用的语言也许不支持队列。 你可以使用 list 列表或者 deque双端队列来模拟一个队列 , 只要是标准的队列操作即可。 示例输入[MyStack, push, push, top, pop, empty][[], [1], [2], [], [], []]输出[null, null, null, 2, 2, false]解释MyStack myStack new MyStack();myStack.push(1);myStack.push(2);myStack.top(); // 返回 2myStack.pop(); // 返回 2myStack.empty(); // 返回 False 提示 * 1 x 9 * 最多调用100 次 push、pop、top 和 empty * 每次调用 pop 和 top 都保证栈不为空 进阶你能否仅用一个队列来实现栈。https://leetcode.cn/problems/implement-stack-using-queues/1.题目解析只使用队列实现栈的push(x) pop() top() empty()2.解题思路队列是先进先出栈是后进先出。准备两个队列queueint q1; queueint q2;规定q1.front()始终表示栈顶。插入新元素x时先把x放入空队列q2将q1中原来的元素依次转移到q2交换q1和q2。例如原来的栈为栈顶 - 3 2 1对应队列队头 - 3 2 1插入4时q24然后把q1中的元素转移过来q24 3 2 1所以新元素4位于队头也就相当于栈顶。3.代码实现class MyStack { public: void push(int x) { // 新元素先进入辅助队列 q2.push(x); // 将原来的元素移动到新元素后面 while (!q1.empty()) { q2.push(q1.front()); q1.pop(); } // q1继续作为主队列 swap(q1, q2); } int pop() { int value q1.front(); q1.pop(); return value; } int top() { return q1.front(); } bool empty() { return q1.empty(); } private: queueint q1; queueint q2; };三.priority_queue1. 基本特点priority_queue称为优先队列。普通队列按照进入顺序出队优先队列则按照元素的优先级出队。默认情况下数值越大的元素优先级越高。priority_queue的底层结构是堆默认使用vector存储数据。插入顺序3 1 8 5 弹出顺序8 5 3 12. 常用接口接口功能时间复杂度priority_queueT pq构造一个空优先队列O(1)pq.empty()判断是否为空O(1)pq.size()返回元素个数O(1)pq.top()访问优先级最高的元素O(1)pq.push(x)插入元素O(log N)pq.pop()删除优先级最高的元素O(log N)3. 大堆与小堆priority_queue默认创建大堆堆顶是最大元素priority_queueint pq; pq.push(3); pq.push(8); pq.push(1); cout pq.top() endl; // 8使用greater创建小堆堆顶是最小元素priority_queueint, vectorint, greaterint pq; pq.push(3); pq.push(8); pq.push(1); cout pq.top() endl; // 1小堆需要包含#include functional模板参数含义priority_queue int, // 元素类型 vectorint, // 底层容器 greaterint // 比较方式 pq;可以简单记忆为priority_queueint // 大堆 priority_queueint, vectorint, greaterint // 小堆4. 使用特点top()表示优先级最高的元素它不一定是最先插入的元素priority_queueint pq; pq.push(10); pq.push(50); pq.push(20); cout pq.top() endl; // 50pop()同样不返回元素int value pq.top(); pq.pop();不支持遍历和随机访问priority_queue不提供迭代器也不能使用下标访问。只能不断读取并删除堆顶while (!pq.empty()) { cout pq.top() ; pq.pop(); }5.数组中的第K大个最大元素215. 数组中的第K个最大元素 - 力扣LeetCode215. 数组中的第K个最大元素 - 给定整数数组 nums 和整数 k请返回数组中第 k 个最大的元素。请注意你需要找的是数组排序后的第 k 个最大的元素而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1:输入: [3,2,1,5,6,4], k 2输出: 5示例 2:输入: [3,2,3,1,2,4,5,5,6], k 4输出: 4 提示 * 1 k nums.length 105 * -104 nums[i] 104https://leetcode.cn/problems/kth-largest-element-in-an-array/1.题目解析给定整数数组nums和整数k返回数组中第k个最大的元素。注意是排序后的第k大不是第k个不同的元素。例如nums [3,2,1,5,6,4] k 2排序后为6 5 4 3 2 1第二大的元素是5。2.思路priority_queueint默认是大堆堆顶始终是当前最大元素。处理步骤将数组中的所有元素放入大堆弹出前k-1个最大元素此时堆顶就是第k大的元素。例如堆顶弹出顺序6、5、4、3、2、1当k 2时只需要弹出最大的6剩下的堆顶5就是答案。3.代码class Solution { public: int findKthLargest(vectorint nums, int k) { // 使用数组区间直接构造大堆 priority_queueint pq(nums.begin(), nums.end()); // 删除前k-1个最大元素 for (int i 0; i k - 1; i) { pq.pop(); } // 此时堆顶就是第k大的元素 return pq.top(); } };也可以逐个插入priority_queueint pq; for (int value : nums) { pq.push(value); }总结stack、queue和priority_queue都属于容器适配器它们在底层容器的基础上提供不同的元素访问与删除规则。stack遵循后进先出原则通过top()访问栈顶适合解决括号匹配等问题queue遵循先进先出原则通过front()访问队头适合按顺序处理数据priority_queue按优先级取出元素默认使用大堆也可以通过greater创建小堆适合求最大值、最小值以及处理 Top K 问题。使用时需要注意三者的pop()都只删除元素不返回元素访问或删除元素前应保证容器非空。掌握它们各自的处理顺序和常用接口才能根据具体问题选择合适的工具。

相关新闻

Spring Boot+Vue法律咨询系统:状态机与事务实践

Spring Boot+Vue法律咨询系统:状态机与事务实践

简介:一份基于Spring Boot与Vue的法律咨询系统完整项目包,面向Java全栈学习者、毕业设计选题学生及律师平台开发者。后端采用Spring Boot 2.7、Spring Security与JWT实现认证授权,结合Redis缓存、WebSocket实时通信、MySQL 8.0存储及阿里云OS…

2026/10/18 14:43:43 阅读更多 →
Linux 进程

Linux 进程

本次内容:1.理解进程概念,了解PCB2.学习进程状态,学会创建进程,掌握僵尸进程和孤儿进程,及其形成原因和危害3.了解进程调度,Linux进程优先级,理解竞争性与独立性,理解并行与并发4.理…

2026/10/18 14:42:42 阅读更多 →
C#调用C++结构体:跨语言内存布局与P/Invoke实战指南

C#调用C++结构体:跨语言内存布局与P/Invoke实战指南

简介:本资源是一套完整的C#调用C结构体混合编程实战项目,面向Windows平台下需打通托管与非托管代码的中高级开发者,解决跨语言数据结构互通、内存安全传递及DLL互操作等核心难题。压缩包共57个文件,包含3个C源文件(.cp…

2026/10/18 14:42:42 阅读更多 →

最新新闻

HWFW_GUI华为ONT固件逆向工具环境配置指南

HWFW_GUI华为ONT固件逆向工具环境配置指南

简介:HWFW_GUI是一款面向通信设备开发与逆向分析工程师的华为ONT固件可视化编辑工具,基于C开发,专用于解析、浏览、修改及导出华为光猫(ONT)固件镜像中的子项目(如uboot、kernel、rootfs等)&…

2026/10/18 15:25:02 阅读更多 →
SwiftUI macOS开发:单选组实现、美化与流式布局实践

SwiftUI macOS开发:单选组实现、美化与流式布局实践

把iOS的SwiftUI代码直接搬到macOS上跑,第一个让我愣住的就是Picker。同一个控件,在iOS上默认是滚动选择或跳转列表,到了macOS里却变成一个干干净净的下拉框;改成Segment分段样式之后,iOS上白白胖胖的控件到了macOS上立…

2026/10/18 15:25:02 阅读更多 →
cy163客服系统22.0.0全开源版:生产级实时会话路由与三端接入底座

cy163客服系统22.0.0全开源版:生产级实时会话路由与三端接入底座

简介:聚合客服(万能客服)cy163_customerservice 22.0.0 全开源版安装更新一体包,是一款面向中小企业、开发者及技术团队的轻量级多渠道客服系统解决方案,聚焦解决客户咨询分散、响应滞后、知识复用率低等典型服务痛点。…

2026/10/18 15:25:02 阅读更多 →
Unity UI核心RectTransform详解:锚点、Pivot与屏幕适配实战

Unity UI核心RectTransform详解:锚点、Pivot与屏幕适配实战

做Unity UI开发,绕不开RectTransform。无论是摆一张图片、做按钮、搭Panel,还是处理不同分辨率下的适配,本质上都是在跟RectTransform打交道。很多初学者一上来就被Inspector里的Position(Pos X、Pos Y、Pos Z)、Width…

2026/10/18 15:25:02 阅读更多 →
老照片上色全攻略:三种实用方法一次掌握

老照片上色全攻略:三种实用方法一次掌握

黑白老照片上色这事,我做了不少年,从最早的画笔一点一点涂,到后来用图层混合模式偷懒,再到现在AI一键生成打底稿,整套流程算是踩过不少坑也攒了不少心得。这个标题其实点得很准——上色本身不难,难的是“简…

2026/10/18 15:25:02 阅读更多 →
MATLAB脑电信号预处理实战:避开基线漂移与眼电伪迹的5大深坑

MATLAB脑电信号预处理实战:避开基线漂移与眼电伪迹的5大深坑

简介:本资源是一套基于MATLAB实现脑电信号情绪分类的完整分析方案,面向生物医学工程、神经科学及人工智能交叉领域的初学者与进阶学习者,聚焦EEG信号预处理、特征提取与多情绪状态(愤怒、平静、悲伤)分类建模。压缩包共…

2026/10/18 15:24:02 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →