跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ Stack 与 Queue 核心用法:基础操作、场景与实战

C++ Stack 和 Queue 是标准库中重要的适配器容器,分别遵循后进先出(LIFO)和先进先出(FIFO)原则。详细解析了它们的头文件引入、常用接口(push/pop/top/front/back 等)及底层实现差异,并通过最小栈、逆波兰表达式求值、二叉树层序遍历等经典算法题,演示了如何在实际开发中灵活运用这两种数据结构解决具体问题。掌握其核心特性有助于优化代码逻辑,提升算法解题效率。

修罗发布于 2026/3/16更新于 2026/7/2131 浏览
C++ Stack 与 Queue 核心用法:基础操作、场景与实战

前言

stack(栈)和 queue(队列)是 C++ 标准库中两种常用的适配器容器。它们的核心价值在于提供严格的数据访问规则——后进先出(LIFO)或先进先出(FIFO),广泛应用于算法设计和业务逻辑实现。本文聚焦实际使用,通过清晰的接口说明和场景示例,帮你快速掌握这两种容器的用法。

一、Stack 与 Queue 的核心特性

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

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

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

二、Stack(栈):后进先出(LIFO)的容器

2.1 核心特性

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

参考文档:stack - C++ Reference

2.2 头文件与定义

#include <stack>
using namespace std;

// 定义栈:默认存储 int 类型,底层依赖 deque 实现
stack<int> st;

// 可指定底层容器(如 vector、list)
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_t)cout << 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();
    return 0;
}

三、Queue(队列):先进先出(FIFO)的容器

3.1 核心特性

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

参考文档:queue - C++ Reference

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_queue();
    return 0;
}

四、实战练习题

4.1 最小栈

题目链接:

155. 最小栈 - 力扣(LeetCode)

题目描述:

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

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();
 */

思路解析: 维护两个栈,主栈 _st 存储所有数据,辅助栈 _minst 存储当前的最小值。每次压入新元素时,如果它小于等于辅助栈顶,也压入辅助栈。弹出时,如果主栈顶等于辅助栈顶,则同时弹出。这样就能保证 getMin() 是 O(1) 时间复杂度。

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();
    }
};

思路解析: 遇到数字入栈,遇到运算符则弹出两个数字进行计算,结果再压回栈中。注意减法和除法要注意操作数的顺序(left 是栈顶弹出的第二个,right 是第一个)。

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);
            // 现在的 levelSize 等于当前队列的 size
            levelSize = q.size();
        }
        return vv;
    }
};

思路解析: 利用队列的特性,每次处理完当前层的所有节点后,更新下一层的节点数量 levelSize。这样就能准确地将每一层的节点放入单独的 vector 中。


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

目录

  1. 前言
  2. 一、Stack 与 Queue 的核心特性
  3. 二、Stack(栈):后进先出(LIFO)的容器
  4. 2.1 核心特性
  5. 2.2 头文件与定义
  6. 2.3 常用接口全解析
  7. 2.4 基础用法演示
  8. 三、Queue(队列):先进先出(FIFO)的容器
  9. 3.1 核心特性
  10. 3.2 头文件与定义
  11. 3.3 常用接口全解析
  12. 3.4 基础用法演示
  13. 四、实战练习题
  14. 4.1 最小栈
  15. 4.2 栈的压入、弹出序列
  16. 4.3 逆波兰表达式求值
  17. 4.4 二叉树的层序遍历
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Ubuntu 22.04 下 libwebkit2gtk-4.1-0 安装避坑指南
  • Python 快速入门指南:基础语法与环境搭建
  • Flood Fill 算法实战:从图像渲染到岛屿问题
  • 评估微调后大模型实际业务效果的性能指标有哪些
  • MySQL 索引底层原理、B+ 树演进与操作实战
  • Python FastAPI 入门实战:从环境搭建到数据模型
  • 通义万相 2.1 多模态生成技术解析与实战应用
  • 基于 Web 的旅游信息交互网站设计与实现
  • 20 道产品经理经典面试题深度解析与应对策略
  • C++ 智能指针详解:RAII 思想与 shared_ptr 原理
  • 基于 Lycium 在鸿蒙设备上验证 C/C++ 交叉编译库
  • 反无人机技术:原理、检测与反制手段
  • OpenClaw QQ 机器人接入实战指南
  • WordPress 基础配置与 Spring Boot MyBatis-Plus 开发实战
  • Whisper v0.2 本地语音转文字工具安装与使用指南
  • AI 时代超级能动性:重建个人掌控力的关键能力
  • OpenClaw 配置飞书机器人完整指南
  • 国内近 200 个 AI 大模型,为何暂无能全面超越 GPT-4o 者?
  • SpringCloud 注册中心与服务注册发现 Eureka 详解
  • C++ Qt 网络编程实战:UDP、TCP 与 HTTP 详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online