C++ 容器是标准模板库(STL)的核心组成部分,本质上是用于存储和组织数据的通用数据结构,它们被封装成模板类,支持不同类型的数据存储,无需你手动管理内存(大部分情况下)。

一、容器的分类

C++ STL 容器主要分为三大类,各自有不同的适用场景:

容器类型代表容器核心特点
序列式容器vector、list、deque元素按插入顺序排列,可通过位置访问,底层结构不同导致性能差异
关联式容器map/set、unordered_map/unordered_set元素按特定规则(排序 / 哈希)组织,查找效率高
容器适配器stack、queue、priority_queue基于基础容器封装,提供特定的访问规则(如栈的后进先出)

二、常用容器的基本用法

下面通过代码示例展示最常用容器的核心操作:

1. 序列式容器 - vector(最常用)

vector 是动态数组,内存连续,随机访问快,尾部增删效率高,中间增删效率低。

cpp

运行

#include <iostream>
#include <vector>  // 包含vector头文件
using namespace std;

int main() {
    // 1. 创建vector
    vector<int> vec;  // 空的int类型vector
    vector<int> vec2(5, 10);  // 初始化5个元素,每个值为10

    // 2. 添加元素
    vec.push_back(1);  // 尾部添加元素1
    vec.push_back(2);
    vec.push_back(3);

    // 3. 访问元素
    cout << "通过下标访问:" << vec[0] << endl;  // 下标访问(无越界检查)
    cout << "通过at访问:" << vec.at(1) << endl;  // at访问(有越界检查,更安全)
    cout << "第一个元素:" << vec.front() << endl;
    cout << "最后一个元素:" << vec.back() << endl;

    // 4. 遍历元素
    cout << "遍历vector:";
    for (int i = 0; i < vec.size(); ++i) {
        cout << vec[i] << " ";
    }
    cout << endl;

    // 5. 删除元素
    vec.pop_back();  // 删除尾部元素
    cout << "删除尾部后大小:" << vec.size() << endl;

    // 6. 清空容器
    vec.clear();
    cout << "清空后是否为空:" << (vec.empty() ? "是" : "否") << endl;

    return 0;
}

输出结果

plaintext

通过下标访问:1
通过at访问:2
第一个元素:1
最后一个元素:3
遍历vector:1 2 3 
删除尾部后大小:2
清空后是否为空:是
2. 关联式容器 - map(键值对)

map 是有序的键值对容器,键唯一,底层是红黑树,查找 / 插入 / 删除效率为 O (log n)。

cpp

运行

#include <iostream>
#include <map>  // 包含map头文件
#include <string>
using namespace std;

int main() {
    // 1. 创建map(键:string,值:int)
    map<string, int> scoreMap;

    // 2. 插入元素
    scoreMap["张三"] = 90;
    scoreMap.insert(pair<string, int>("李四", 85));
    scoreMap.insert({"王五", 95});

    // 3. 访问元素
    cout << "张三的分数:" << scoreMap["张三"] << endl;
    // 查找不存在的键会自动插入默认值(0),建议用find
    auto it = scoreMap.find("赵六");
    if (it != scoreMap.end()) {
        cout << "赵六的分数:" << it->second << endl;
    } else {
        cout << "未找到赵六的分数" << endl;
    }

    // 4. 遍历map
    cout << "\n所有分数:" << endl;
    for (const auto& pair : scoreMap) {  // 范围for循环
        cout << pair.first << ":" << pair.second << endl;
    }

    // 5. 删除元素
    scoreMap.erase("李四");
    cout << "\n删除李四后,元素数量:" << scoreMap.size() << endl;

    return 0;
}

输出结果

plaintext

张三的分数:90
未找到赵六的分数

所有分数:
李四:85
王五:95
张三:90

删除李四后,元素数量:2
3. 容器适配器 - stack(栈)

stack 是后进先出(LIFO)的适配器,默认基于 deque 实现,只能访问栈顶元素。

cpp

运行

#include <iostream>
#include <stack>  // 包含stack头文件
using namespace std;

int main() {
    stack<int> s;

    // 入栈
    s.push(10);
    s.push(20);
    s.push(30);

    // 访问栈顶
    cout << "栈顶元素:" << s.top() << endl;

    // 出栈
    s.pop();
    cout << "出栈后栈顶:" << s.top() << endl;

    // 栈的大小
    cout << "栈的大小:" << s.size() << endl;

    // 判断是否为空
    cout << "栈是否为空:" << (s.empty() ? "是" : "否") << endl;

    return 0;
}

输出结果

plaintext

栈顶元素:30
出栈后栈顶:20
栈的大小:2
栈是否为空:否

三、容器选择的核心原则

  1. 如果需要随机访问(按下标快速取值)、尾部增删多 → 选 vector
  2. 如果需要频繁在中间增删 → 选 list(双向链表)
  3. 如果需要键值对存储、按键查找 → 有序选 map,无序且追求更快查找 → 选 unordered_map
  4. 如果需要去重 → 选 set/unordered_set
  5. 如果需要先进先出(队列)→ 选 queue后进先出(栈)→ 选 stack

总结

  1. C++ 容器是 STL 的核心,分为序列式、关联式、容器适配器三类,适配不同的数据存储和访问场景。
  2. vector 是最常用的序列式容器,适合随机访问;map 适合键值对存储;stack/queue 适合特定访问规则。
  3. 选择容器的核心依据是访问方式增删操作的位置 / 频率,优先选择匹配业务场景、效率更高的容器。

更多推荐