C++ STL 容器详解:vector、deque 与 stack 完全指南

关键词: C++ STL、标准模板库、vector 向量容器、deque 双端队列、stack 栈容器、序列式容器、容器适配器、动态数组、LIFO、C++ 数据结构


STL 标准模板库概述

STLStandard Template Library(标准模板库)的简称,由惠普实验室(Hewlett-Packard Labs)开发的一系列软件的统称。它由 Alexander StepanovMeng LeeDavid R. Musser 在惠普实验室工作期间共同设计开发。

从根本上说,STL 是一些**容器(Container)的集合,包含 listvectorsetmap 等;STL 同时也是算法(Algorithm)**和其他组件的集合。这里的"容器"和"算法"凝聚了世界上众多优秀开发者多年来的智慧结晶。

STL 的核心目标: 标准化组件,让开发者无需重复造轮子,直接复用现成的高质量组件。STL 是 C++ 标准库的一部分,无需额外安装任何库文件。

STL 版本众多,常见的有 HP STLPJ STLSGI STL 等。

在 C++ 标准中,STL 被组织为以下 13 个头文件

头文件 功能领域
<algorithm> 通用算法(排序、查找、遍历等)
<deque> 双端队列容器
<functional> 函数对象与绑定器
<iterator> 迭代器相关工具
<vector> 向量(动态数组)容器
<list> 双向链表容器
<map> 关联容器(键值对映射)
<memory> 智能指针与内存管理
<numeric> 数值算法
<queue> 队列与优先级队列容器适配器
<set> 集合容器
<stack> 栈容器适配器
<utility> 通用工具(pair、move 等)

一、vector 向量容器

1.1 什么是 vector?

序列式容器 vector(向量):连续存储的元素,定义在 <vector> 头文件中。

vector 容器是 STL 中最常用的容器之一,它和 array 容器非常类似,都可以看作是对 C++ 普通数组的升级版

vector 与 array 的关键区别:

特性 array vector
数组类型 静态数组(容量固定) 动态数组(容量可变)
内存管理 手动管理 自动调整,无需人工干预
元素插入/删除 不支持 支持动态增减

vector 常被称为向量容器,该容器的核心性能特征如下:

  • 尾部操作: 在尾部插入或删除元素,时间复杂度为 O(1)(常数时间)
  • 头部/中部操作: 在头部或中部插入/删除元素,需要移动后续元素,时间复杂度为 O(n)(线性时间)

1.2 创建 vector 容器的多种方式

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 方式1:创建存储 double 类型的空 vector 容器
    vector<double> v1;

    // 方式2:创建 int 类型的 vector 容器,并初始化元素
    vector<int> v2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // 方式3:创建 vector 容器,指定元素个数为 50(默认值初始化)
    vector<int> v3(50);

    // 方式4:创建 vector 容器,拥有 10 个值为 'A' 的字符
    vector<char> v4(10, 'A');

    // 方式5:拷贝构造——将 v4 赋值给 v5
    vector<char> v5(v4);

    // 方式6:通过数组指针范围初始化
    int a[] = { 10, 20, 30 };
    vector<int> v6(a, a + 2);   // v6 将保存 {10, 20}

    // 方式7:通过另一个容器的迭代器范围初始化
    vector<int> v7{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    vector<int> v8(begin(v7), begin(v7) + 3);   // v8 将保存 {1, 2, 3}

    return 0;
}

1.3 vector 容器基本操作示例

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 定义一个 vector 字符容器
    vector<char> v1;

    // 向容器尾部依次添加字符 "STLTEMPLATE"
    v1.push_back('S');
    v1.push_back('T');
    v1.push_back('L');
    v1.push_back('T');
    v1.push_back('E');
    v1.push_back('M');
    v1.push_back('P');
    v1.push_back('L');
    v1.push_back('A');
    v1.push_back('T');
    v1.push_back('E');

    // 输出容器 v1 的元素个数
    cout << "元素个数为:" << v1.size() << endl;

    // 遍历容器(使用迭代器)
    cout << "\n输出 v1 容器中的元素:\n";
    for (auto i = v1.begin(); i < v1.end(); i++) {
        cout << " " << *i << " ";
    }

    /****************************************************************/
    // 在头部位置插入数据元素
    v1.insert(v1.begin(), 'V');

    // 遍历容器
    cout << "\n输出 v1 容器中的元素:\n";
    for (auto i = v1.begin(); i < v1.end(); i++) {
        cout << " " << *i << " ";
    }

    /****************************************************************/
    // 在尾部位置插入数据元素
    v1.insert(v1.end(), 'I');

    // 遍历容器
    cout << "\n输出 v1 容器中的元素:\n";
    for (auto i = v1.begin(); i < v1.end(); i++) {
        cout << " " << *i << " ";
    }
    cout << endl;

    // 通过 at() 访问首元素(带边界检查)
    cout << "输出 v1 容器首个元素为:" << v1.at(0) << endl;

    return 0;
}

1.4 vector 成员函数速查

vector 容器成员函数非常丰富,推荐直接查阅官方文档:

cplusplus.com — vector 参考手册


二、deque 双端队列容器

2.1 什么是 deque?

dequedouble-ended queue(双端队列)的缩写,又称双端队列容器

前面已经介绍过 vector 容器。deque 容器和 vector 容器有很多相似之处:

  • deque 同样擅长在序列尾部添加或删除元素,时间复杂度为 O(1)
  • deque 同样不擅长在序列中部添加或删除元素
  • deque 也可以根据需要动态修改自身的容量和大小

deque 与 vector 的关键区别:

特性 vector deque
尾部操作(增/删) O(1) O(1)
头部操作(增/删) O(n) O(1)
中部操作(增/删) O(n) O(n)
内存连续性 连续存储 不保证连续
动态调整容量

🎯 使用建议: 当需要向序列两端频繁添加或删除元素时,应首选 deque 容器

尤其重要的是,deque 容器中存储的元素不能保证所有元素都存储在连续的内存空间中,这是它与 vector 的重要区别之一。

2.2 创建 deque 容器

#include <iostream>
#include <deque>
using namespace std;

int main() {
    // 方式1:创建空的 deque 容器,没有任何数据元素
    deque<int> d1;

    // 方式2:创建 deque 容器,指定 50 个元素(默认值初始化)
    deque<int> d2(50);

    // 方式3:创建具有 9 个元素的 deque 容器,且全部初始化为 888
    deque<int> d3(9, 888);

    // 方式4:容器之间直接赋值(拷贝构造)
    deque<int> d4(10);
    deque<int> d5(d4);

    return 0;
}

2.3 deque 增删操作示例

#include <iostream>
#include <deque>
using namespace std;

int main() {
    // 定义空的 deque 容器
    deque<int> d1;

    // 向容器尾部依次插入数字 1~10
    d1.push_back(1);
    d1.push_back(2);
    d1.push_back(3);
    d1.push_back(4);
    d1.push_back(5);
    d1.push_back(6);
    d1.push_back(7);
    d1.push_back(8);
    d1.push_back(9);
    d1.push_back(10);

    // 输出 d1 的元素个数
    cout << "输出 d1 容器元素的个数为:" << d1.size() << endl;

    // 向 d1 容器尾部添加元素 888
    d1.push_back(888);

    cout << "输出 d1 容器元素的所有值:" << endl;
    for (auto i = d1.begin(); i < d1.end(); i++) {
        cout << " " << *i << " ";
    }
    cout << endl << endl;

    // 删除容器头部的数据元素
    d1.pop_front();
    cout << "输出 d1 容器元素的所有值:" << endl;
    for (auto i = d1.begin(); i < d1.end(); i++) {
        cout << " " << *i << " ";
    }
    cout << endl << endl;

    // 删除容器尾部的数据元素
    d1.pop_back();
    cout << "输出 d1 容器元素的所有值:" << endl;
    for (auto i = d1.begin(); i < d1.end(); i++) {
        cout << " " << *i << " ";
    }
    cout << endl << endl;

    return 0;
}

deque 运行结果

2.4 deque 成员函数速查

deque 容器成员函数非常丰富,推荐直接查阅官方文档:

cppreference.com — std::deque 参考手册


三、stack 栈容器适配器

3.1 什么是容器适配器?什么是 stack?

容器适配器是一个封装了序列容器的类模板,它在一般序列容器的基础上提供了不同风格的功能接口。之所以称为"适配器",是因为它通过适配(包装)现有容器的接口来提供新的功能语义。

stack<T> 容器适配器中的数据以 LIFO(Last In, First Out,后进先出) 的方式组织,这与日常生活中的很多场景类似:

  • 自助餐厅中堆叠的盘子(后放的先被取走)
  • 箱子中堆叠的书本(最上面一本最先被拿到)
  • 弹夹中的子弹(后压入的先射出)

stack 的核心限制: 只能访问栈顶(top)元素;只有在移除栈顶元素后,才能访问其下方的元素。

3.2 创建与使用 stack 容器

#include <iostream>
#include <stack>
#include <list>
using namespace std;

int main() {
    // 创建一个 stack 容器适配器,底层使用 list 作为存储容器
    list<int> LS{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    stack<int, list<int>> mystack(LS);

    // 查询 mystack 存储元素的个数
    cout << "栈容器数据元素个数为:" << mystack.size() << endl;

    // 输出栈容器数据元素的值(LIFO 顺序:从栈顶到栈底)
    cout << "输出栈容器数据元素的值:" << endl;
    while (!mystack.empty()) {      // empty() 为空返回 true,否则返回 false
        cout << mystack.top() << " "; // top():访问栈顶元素
        mystack.pop();               // pop():弹出栈顶元素
    }

    return 0;
}

stack 运行结果

3.3 stack 成员函数速查

stack 容器成员函数推荐直接查阅官方文档:

cplusplus.com — stack 参考手册


三容器对比总结

对比维度 vector deque stack
类型 序列式容器 序列式容器 容器适配器
数据结构 动态数组 双端队列 LIFO 栈
内存布局 连续存储 分段连续(不保证整体连续) 取决于底层容器
尾部插入 O(1) O(1) O(1)(push)
尾部删除 O(1) O(1) O(1)(pop)
头部插入 O(n) O(1) 不可用
头部删除 O(n) O(1) 不可用
随机访问 O(1) O(1) 不可用
中间操作 O(n) O(n) 不可用
头文件 <vector> <deque> <stack>
适用场景 频繁尾部操作 + 随机访问 频繁两端操作 后进先出场景

选择建议:

  • 需要动态数组 + 随机访问 → vector
  • 需要双端高效插入/删除 → deque
  • 需要 LIFO 约束(如递归模拟、括号匹配、表达式求值) → stack

更多推荐