C++ :Stack 与 Queue 完全使用指南(基础操作 + 经典场景 + 实战习题)

一. 先搞懂基础:Stack 与 Queue 的核心特性

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

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

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

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

2.1 核心特性:

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

参考文档stack - C++ Reference

2.2 头文件与定义

cpp 复制代码
#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.top() |
| top() | 返回栈顶元素的引用(可直接读取或修改栈顶值),需先确保栈非空 | int x = st.top();(读取);st.top() = 20;(修改) |
| sizie() | 返回栈中当前存储的元素总个数,返回值为无符号整数(size_t) | cout << st.size(); |
| empty() | 判断栈是否为空,若栈中无元素则返回 true,否则返回 false | if (st.empty()) { ... } |

2.4 基础用法演示

cpp 复制代码
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(队列):先进先出(FIFO)的容器

3.1 核心特性:

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

参考文档queue - C++ Reference

3.2 头文件与定义:

cpp 复制代码
#include <queue>  // 必须包含的头文件
using namespace std;

// 定义队列:默认底层依赖deque实现
queue<int> q;

// 可指定底层容器(如list,不建议用vector,因vector头删效率低)
queue<int, list<int>> q_l;  // 基于list的队列

3.3 常用接口全解析

|-----------|------------------------------------------------------------------------|-----------------------------------------------------------|
| 接口 | 功能描述 | 示例 |
| push(val) | 向队列的队尾添加一个元素,新元素成为队列的最后一个元素,操作后队列长度+1 | q.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 基础用法演示

cpp 复制代码
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++算法代码

cpp 复制代码
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++算法代码

cpp 复制代码
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();
    }
};

图解

相关推荐
Jun6265 小时前
QT(2)-通过管道关联CMD
开发语言·qt·命令模式
程序员老舅5 小时前
从内核视角,看Linux文件读写过程
linux·服务器·c++·内核·linux内核·vfs·linux内存
Soari5 小时前
llama.cpp更新(b9553):LLM inference in C/C++,本地和云端实现高性能大模型推理
c语言·c++·llama
Deep-w5 小时前
【MATLAB】基于离散 LQR 的车辆横向轨迹跟踪控制方法研究
开发语言·算法·matlab
2601_961194026 小时前
考研资料电子版|去哪找|网盘
java·c语言·c++·python·考研·php
Peter·Pan爱编程6 小时前
23. 算法库:用算法代替手写循环
c++·人工智能·算法
于先生吖6 小时前
前后端分离二手商城开发,质检登记、回收回款整套业务源码部署教程
java·开发语言·uni-app
codeejun6 小时前
每日一Go-76(架构篇)|多集群部署 / 容灾 / Failover / Backup / 热迁移
开发语言·架构·golang
战族狼魂6 小时前
从零构建企业级Hermes-Agent:复杂任务拆解、工具协同与安全落地实践
开发语言·人工智能·python
阿里嘎多学长6 小时前
2026-06-08 GitHub 热点项目精选
开发语言·程序员·github·代码托管