《C++ Stack与Queue详解掌握指南》:带领你从基础夯实到玩转栈与队列容器

《C++ Stack与Queue详解掌握指南》:带领你从基础夯实到玩转栈与队列容器

🔥个人主页:Cx330🌸

❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》

《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔

🌟心向往之行必能至


🎥Cx330🌸的简介:


目录

前言:

一. 基础夯实:Stack 与 Queue 的核心特性

二. Stack(栈):后进先出

2.1 核心特性:

2.2 头文件与定义

2.3 常用接口大全

2.4 用法演示

三. Queue(队列):先进先出

3.1 核心特性:

3.2 头文件与定义:

3.3 常用接口大全

3.4 用法演示

四. 实战练习题

4.1 最小栈

4.2 栈的压入、弹出序列

4.3 逆波兰表达式求值

4.4 二叉树的层序遍历

结尾:


前言:

stack(栈)和 queue(队列)是 C++ 标准库中两种常用的适配器容器,它们的核心价值在于提供严格的数据访问规则(栈->后进先出 ,队列->先进先出),这篇博客将着重于实际使用来帮助你快速掌握这两个容器的使用

一. 基础夯实:Stack 与 Queue 的核心特性

在写代码前,首先要明确两者的 “数据访问规则”—— 这是它们区别于其他容器的关键:

容器核心规则访问特性适用场景
stack后进先出仅能访问“栈顶”元素函数调用栈、表达式求值、撤销操作
queue先进先出仅能访问“队头”和“队尾”元素任务调度、消息队列、广度优先搜索

两者的共性是 “限制访问”:不支持随机访问(如 [] 下标),也不支持迭代器遍历 —— 目的是强制遵循其数据规则,避免错误的访问方式


二. Stack(栈):后进先出

2.1 核心特性:

  • 访问规则:只能从"栈顶"添加或删除元素(最后入栈的元素最先出栈)
  • 适用场景:函数调用栈,表达式求值等

2.2 头文件与定义

#include <stack> //头文件 using namespace std; // 定义栈:默认存储int类型,底层依赖deque实现 stack<int> st; // 可指定底层容器 stack<int, vector<int>> st_v; // 基于vector的栈 stack<int, list<int>> st_l; // 基于list链表的栈 

2.3 常用接口大全

接口功能描述示例
push(val)向栈顶添加元素,新元素成为新的栈顶st.push(10)
pop()删除当前栈顶元素(操作后原栈顶的下一个元素成为新栈顶),无返回值,需先确保栈非空st.pop()
top()返回栈顶元素的引用(可直接读取或修改栈顶值),需先确保栈非空int x = st.top();(读取);st.top() = 20;(修改)
size()返回栈中当前存储的元素总个数,返回值为无符号整数(size_tcout << st.size();
empty()判断栈是否为空,若栈中无元素则返回 true,否则返回 falseif (!st.empty()) { ... }

2.4 用法演示

void test_stack() { stack<int> st; st.push(1); st.push(2); st.push(3); st.emplace(4); while (!st.empty()) { cout << st.top() << " "; st.pop(); } cout << endl; } int main() { test_stack(); } 

三. Queue(队列):先进先出

3.1 核心特性:

  • 访问规则:从"队尾"添加元素,从"队头"删除元素(最先入队的元素最先出队)
  • 适用场景:任务调度(如打印队列)、消息队列、广度优先搜索

3.2 头文件与定义:

#include <queue> // 头文件 using namespace std; // 定义队列:默认底层依赖deque实现 queue<int> q; // 可指定底层容器(如list,不建议用vector,因vector头删效率低) queue<int, list<int>> q_l; // 基于list的队列 

3.3 常用接口大全

接口功能描述示例
push(val)向队列的队尾添加一个元素,新元素成为队列的最后一个元素,操作后队列长度+1q.push("任务1");
pop()删除队列的队头元素(即最早入队的元素),操作后队列长度-1,无返回值(需先通过 front() 获取队头元素再删除)q.pop();
front()返回队列队头元素的引用(可读取或修改),仅访问不删除,需确保队列非空

string task = q.front();读取);

q.front() = "优先任务1";(修改)

back()返回队列队尾元素的引用(可读取或修改),仅访问不删除,需确保队列非空string last = q.back();(读取);q.back() = "最后任务";(修改)
size()返回队列中当前存储的元素总个数,返回值类型为 size_t(无符号整数)cout << q.size();
empty()判断队列是否为空:若队列中无元素则返回 true,有元素则返回 false,常用于遍历或删除前判断队列状态

if (q.empty())

{ cout << "队列为空"; }

3.4 用法演示

void test_queue() { queue<int> q; q.push(1); q.push(2); q.push(3); q.emplace(4); while (!q.empty()) { cout << q.front() << " "; q.pop(); } cout << endl; } int main() { //test_stack(); test_queue(); } 

四. 实战练习题

4.1 最小栈

题目链接:

155. 最小栈 - 力扣(LeetCode)

题目描述:

图解

C++代码实现

class MinStack { public: MinStack() { //可以啥都不写,甚至可以删掉 //会去调这个自定义类型的默认构造 } void push(int val) { _st.push(val); if(_minst.empty()||_minst.top()>=val) _minst.push(val); } void pop() { if(_minst.top()==_st.top()) _minst.pop(); _st.pop(); } int top() { return _st.top(); } int getMin() { return _minst.top(); } private: stack<int> _st; stack<int> _minst; }; /** * Your MinStack object will be instantiated and called as such: * MinStack* obj = new MinStack(); * obj->push(val); * obj->pop(); * int param_3 = obj->top(); * int param_4 = obj->getMin(); */ 

4.2 栈的压入、弹出序列

题目链接:

栈的压入、弹出序列_牛客题霸_牛客网

题目描述:

图解

C++代码实现

class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param pushV int整型vector * @param popV int整型vector * @return bool布尔型 */ bool IsPopOrder(vector<int>& pushV, vector<int>& popV) { int pushi=0,popi=0; stack<int> st; while(pushi<pushV.size()) { st.push(pushV[pushi]); while(!st.empty()&&st.top()==popV[popi]) { st.pop(); popi++; } pushi++; } return st.empty(); } }; 

4.3 逆波兰表达式求值

题目链接:

150. 逆波兰表达式求值 - 力扣(LeetCode)

题目描述:

图解:

C++代码实现

class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> st; for(auto& str:tokens) { if(str=="+"||str=="-"||str=="*"||str=="/") { //运算符 int right=st.top(); st.pop(); int left=st.top(); st.pop(); switch(str[0]) { case '+': st.push(left+right); break; case '-': st.push(left-right); break; case '*': st.push(left*right); break; case '/': st.push(left/right); break; } } else{ //运算数 st.push(stoi(str)); } } return st.top(); } }; 

4.4 二叉树的层序遍历

题目链接:

102. 二叉树的层序遍历 - 力扣(LeetCode)

题目描述:

图解:

C++代码实现

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode*> q; int levelSize=0; if(root) { q.push(root); levelSize=1; } vector<vector<int>> vv; while(!q.empty()) { vector<int> v; //一层一层的出 while(levelSize--) { TreeNode* front=q.front(); q.pop(); v.push_back(front->val); if(front->left) q.push(front->left); if(front->right) q.push(front->right); } vv.push_back(v); //现在的leveSize等于当前队列的size levelSize=q.size(); } return vv; } }; 

结尾:

往期回顾:

《C++ 手搓list容器底层》:从结构原理深度解析到功能实现(附源码版)

总结:Stack 和 Queue 作为 C++ 标准库中经典的适配器容器,凭借明确的访问规则在各类场景中大显身手。掌握它们的基础操作,再结合实战习题打磨,就能轻松应对算法与业务中的数据管理需求,快去实践吧

Read more

Flutter 三方库 flutter_app_packager 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、自动化、全平台的桌面端安装包打包与工程分发引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 flutter_app_packager 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、自动化、全平台的桌面端安装包打包与工程分发引擎 在鸿蒙(OpenHarmony)系统的桌面端适配(Ohos PC Mode)以及为鸿蒙应用构建配套的 PC 端管理工具(macOS/Windows/Linux 版辅助工具)时,如何通过一套 Dart 代码或命令行指令,即可瞬间将 Flutter 应用转化为原生的 .dmg, .exe 或 .deb 安装包?flutter_app_packager 为开发者提供了一套工业级的、基于 Dart 的自动化打包封装方案。本文将深入实战其在全平台分发工程中的应用。 前言 什么是

By Ne0inhk
做鸿蒙 App 一个月:10 个 ArkUI 大坑

做鸿蒙 App 一个月:10 个 ArkUI 大坑

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名) 大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。 我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案, 在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。 技术方向:前端 / 跨端 / 小程序 / 移动端工程化 内容平台:掘金、知乎、ZEEKLOG、简书 创作特点:实战导向、源码拆解、少空谈多落地 文章状态:长期稳定更新,大量原创输出 我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、

By Ne0inhk
Flutter for OpenHarmony: Flutter 三方库 openid_client 深度打通鸿蒙应用的单点登录 (SSO)(基于 OpenID Connect 标准)

Flutter for OpenHarmony: Flutter 三方库 openid_client 深度打通鸿蒙应用的单点登录 (SSO)(基于 OpenID Connect 标准)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在现代企业级 OpenHarmony 应用中,为了安全和便捷,往往会使用 OpenID Connect (OIDC) 协议进行统一身份认证。无论是集成 Google 登录、GitHub 登录,还是对接企业内部的 Keycloak、Okta 等身份提供商(IdP),我们都需要一个健壮的库来处理繁杂的 OAuth2 握手流程。 openid_client 是一个功能极其全面的 Dart 实现。它能够自动发现服务器端点(Discovery)、处理 PKCE 流程并安全地交换令牌,是构建高安全级别鸿蒙应用的首选。 一、核心认证流程 OIDC 认证流程通常是通过浏览器重定向完成的,openid_client 充当了流程的指挥官。 身份服务器 (IdP)openid_client鸿蒙

By Ne0inhk
本地部署 Stable Diffusion:零基础搭建 AI文生图模型

本地部署 Stable Diffusion:零基础搭建 AI文生图模型

本地部署 Stable Diffusion:零基础搭建 AI 文生图系统 Stable Diffusion 是一款强大的开源文生图(Text-to-Image)AI 模型,可以本地运行,无需联网或付费就能生成高质量图像。相比 Midjourney、DALL·E 等云服务,Stable Diffusion 更自由、更可控。 这篇文章将手把手教你如何使用 Stable Diffusion WebUI(AUTOMATIC1111) 在本地搭建一个高效、可定制的 AI 画图系统,适合 AI 爱好者、程序员和设计师。 ✅ 目录 1. 为什么选择 Stable Diffusion? 2. 环境准备:硬件 & 软件 3. 安装与部署 WebUI 4.

By Ne0inhk