C++从入门到实战(二十二)stack的介绍和使用
- 前言
- 一、什么是stack
-
- [1.1 stack的核心特性](#1.1 stack的核心特性)
- [1.2 stack与序列容器的核心差异](#1.2 stack与序列容器的核心差异)
- 二、stack的核心接口详解
-
- [2.1 构造函数:stack()](#2.1 构造函数:stack())
- [2.2 判空操作:empty()](#2.2 判空操作:empty())
- [2.3 大小获取:size()](#2.3 大小获取:size())
- [2.4 栈顶访问:top()](#2.4 栈顶访问:top())
- [2.5 入栈操作:push()](#2.5 入栈操作:push())
- [2.6 出栈操作:pop()](#2.6 出栈操作:pop())
- 三、stack的综合使用示例
- 四、stack核心接口总结
前言
- 在前几篇博客中,我们系统学习了
vector(动态数组)、list(双向循环链表)、string(动态字符串)等序列式容器------它们都支持随机访问或双向遍历,可直接操作任意位置的元素。 - 本篇将聚焦STL中的适配器容器 ------
stack(栈):它并非独立的容器,而是基于其他序列容器(如deque、vector)封装而成的"适配容器",核心遵循后进先出(LIFO) 原则,仅支持栈顶的插入、删除和访问操作。 - 我们将从
stack的核心特性入手,详解其常用接口的用法、底层实现逻辑,并结合示例说明其典型应用场景,帮助你掌握栈的核心使用技巧。
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
C++官方stack文档
https://cplusplus.com/reference/stack/stack/
一、什么是stack
std::stack 是C++ STL中的容器适配器 (Container Adapter),而非原生容器------它封装了底层序列容器(默认是deque双端队列(后续我们也会详细讲解)),并仅暴露符合"栈"特性的接口,核心规则是:最后入栈的元素最先出栈(LIFO, Last In First Out)。
1.1 stack的核心特性
- 单向操作 :仅能对栈顶 进行插入(
push)、删除(pop)和访问(top)操作,无法访问栈中间或栈底的元素。 - 无随机访问 :不支持下标(
[])、迭代器遍历,也没有begin()/end()接口。 - 适配器特性 :底层可复用
deque、vector、list等序列容器(需满足back()、push_back()、pop_back()、empty()、size()接口),默认选择deque(兼顾效率和内存特性)。 - 轻量级封装 :
stack本身仅提供接口封装,无额外内存开销,性能依赖底层容器。
1.2 stack与序列容器的核心差异
| 对比维度 | stack(栈) |
vector(动态数组) |
list(双向链表) |
|---|---|---|---|
| 访问方式 | 仅栈顶(top()) |
随机访问([]/at()) |
双向遍历(迭代器) |
| 插入/删除位置 | 仅栈顶(push()/pop()) |
任意位置(insert()/erase()) |
任意位置(insert()/erase()) |
| 迭代器支持 | 不支持 | 支持随机访问迭代器 | 支持双向迭代器 |
| 底层实现 | 容器适配器(默认deque) |
连续内存 | 离散节点(双向循环链表) |
| 核心规则 | 后进先出(LIFO) | 顺序存储 | 顺序存储 |
二、stack的核心接口详解
stack的接口极简,仅包含构造、判空、大小、栈顶访问、入栈、出栈6个核心接口,以下是详细说明:
2.1 构造函数:stack()
语法
cpp
stack<T> st; // T为存储的元素类型(如int、string等)
// 或指定底层容器:stack<T, Container> st;
作用
- 创建一个空的栈,底层容器默认初始化(如
deque的默认构造)。
示例
cpp
#include <stack>
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main() {
// 1. 默认构造(底层deque)
stack<int> st1;
// 2. 指定底层容器为vector
stack<int, vector<int>> st2;
// 3. 指定底层容器为list
stack<int, list<int>> st3;
cout << "st1是否为空:" << st1.empty() << endl; // 输出:1(true)
return 0;
}

2.2 判空操作:empty()
语法
cpp
bool empty() const;
作用
- 检测栈是否为空(无元素),为空返回
true,否则返回false。
示例
cpp
stack<int> st;
cout << st.empty() << endl; // 空栈,输出:1(true)
st.push(10);
cout << st.empty() << endl; // 非空,输出:0(false)

2.3 大小获取:size()
语法
cpp
size_t size() const;
作用
- 返回栈中元素的个数,类型为
size_t(无符号整数)。
示例
cpp
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
cout << "栈的大小:" << st.size() << endl; // 输出:3

2.4 栈顶访问:top()
语法
cpp
// 普通版本:返回栈顶元素的引用(可修改)
T& top();
// const版本:返回栈顶元素的const引用(只读)
const T& top() const;
作用
- 返回栈顶元素的引用(栈顶是最后入栈的元素),注意:空栈调用top()会导致未定义行为。
示例
cpp
stack<int> st;
st.push(10);
st.push(20);
// 普通版本:修改栈顶元素
st.top() = 30;
cout << "栈顶元素:" << st.top() << endl; // 输出:30
// const版本:只读
const stack<int> cst(st);
cout << "const栈顶元素:" << cst.top() << endl; // 输出:30
// cst.top() = 40; // 错误!const引用不可修改


2.5 入栈操作:push()
语法
cpp
// 拷贝入栈:将val拷贝到栈顶
void push(const T& val);
// 移动入栈(C++11):将val移动到栈顶(效率更高)
void push(T&& val);
// 原地构造(C++11):直接在栈顶构造元素,避免拷贝
template <class... Args>
void emplace(Args&&... args);
作用
- 将元素添加到栈顶,底层调用容器的
push_back()(或emplace_back())。
示例
cpp
stack<int> st;
// 普通拷贝入栈
st.push(1);
st.push(2);
// emplace原地构造(效果同push(3),但效率更高)
st.emplace(3);
cout << "栈顶元素:" << st.top() << endl; // 输出:3
cout << "栈的大小:" << st.size() << endl; // 输出:3

2.6 出栈操作:pop()
语法
cpp
void pop();
作用
删除栈顶元素(仅删除,不返回),底层调用容器的pop_back();注意:空栈调用pop()会导致未定义行为。
示例
cpp
stack<int> st;
st.push(1);
st.push(2);
st.push(3);
cout << "出栈前栈顶:" << st.top() << endl; // 输出:3
st.pop(); // 删除栈顶元素3
cout << "出栈后栈顶:" << st.top() << endl; // 输出:2
cout << "出栈后大小:" << st.size() << endl; // 输出:2
三、stack的综合使用示例
stack的核心操作是"入栈→访问栈顶→出栈"的循环,以下是完整示例,包含栈的基本操作和"遍历"技巧(stack无迭代器,需借助临时栈):
cpp
#include <stack>
#include <iostream>
using namespace std;
int main() {
// 1. 初始化栈并入栈元素
stack<int> st;
st.push(10);
st.push(20);
st.push(30);
st.push(40);
// 2. 基本属性
cout << "栈是否为空:" << st.empty() << endl; // 输出:0
cout << "栈的大小:" << st.size() << endl; // 输出:4
cout << "栈顶元素:" << st.top() << endl; // 输出:40
// 3. 出栈操作(删除栈顶)
st.pop();
cout << "出栈后栈顶:" << st.top() << endl; // 输出:30
// 4. 模拟遍历栈(需借助临时栈,遍历后原栈为空)
stack<int> temp; // 临时栈
cout << "栈的元素(从栈顶到栈底):";
while (!st.empty()) {
int val = st.top();
cout << val << " "; // 输出:30 20 10
temp.push(val); // 保存到临时栈
st.pop(); // 原栈出栈
}
cout << endl;
// 5. 恢复原栈(从临时栈倒回)
while (!temp.empty()) {
st.push(temp.top());
temp.pop();
}
cout << "恢复后栈的大小:" << st.size() << endl; // 输出:3
return 0;
}
输出结果 :

四、stack核心接口总结
| 接口名 | 语法 | 功能描述 | 注意事项 |
|---|---|---|---|
| 构造 | stack<T> st; |
创建空栈,默认底层容器为deque | 可指定底层容器(如vector/list) |
| empty() | bool empty() const; |
判断栈是否为空,空返回true | 无参数,时间复杂度O(1) |
| size() | size_t size() const; |
返回栈中元素个数 | 返回值为无符号整数 |
| top() | T& top(); |
返回栈顶元素的引用(可修改) | 空栈调用会导致未定义行为 |
| push() | void push(const T& val); |
将val拷贝入栈顶 | 底层调用push_back() |
| emplace() | void emplace(Args&&... args); |
栈顶原地构造元素 | C++11新增,效率高于push() |
| pop() | void pop(); |
删除栈顶元素(无返回值) | 空栈调用会导致未定义行为 |
我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343我的C++知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482
|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |
