C++从入门到实战(二十二)stack的介绍和使用

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(栈):它并非独立的容器,而是基于其他序列容器(如dequevector)封装而成的"适配容器",核心遵循后进先出(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()接口。
  • 适配器特性 :底层可复用dequevectorlist等序列容器(需满足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

|--------------------|
| 非常感谢您的阅读,喜欢的话记得三连哦 |

相关推荐
赵得C6 小时前
2025下半年软件设计师考前几页纸
java·开发语言·分布式·设计模式·性能优化·软考·软件设计师
幸存者letp6 小时前
为什么 max(words, key=len) 中需要传 key=len
服务器·开发语言·c#
weixin_446260856 小时前
FastF1: 轻松获取和分析F1数据的Python包
开发语言·python
Cosmoshhhyyy6 小时前
《Effective Java》解读第26条:请不要使用原生态类型
java·开发语言
郝学胜-神的一滴6 小时前
Linux下创建线程:从入门到实践
linux·服务器·开发语言·c++·程序人生·软件工程
山土成旧客6 小时前
【Python学习打卡-Day22】启航Kaggle:从路径管理到独立项目研究的全方位指南
开发语言·python·学习
我命由我123456 小时前
Python Flask 开发 - Flask 路径参数类型(string、int、float、path、uuid)
服务器·开发语言·后端·python·flask·学习方法·python3.11
FFZero16 小时前
C++ 内存模型与Memory Order深度解析
c++
永远都不秃头的程序员(互关)6 小时前
C++核心语法复盘:数据结构编程的底层基石
开发语言