news 2026/6/25 15:49:03

C++容器全解析与用法示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++容器全解析与用法示例

C++标准库容器主要分为三大类:顺序容器、关联容器和容器适配器。以下是所有标准容器的分类、说明及方法演示。

一、顺序容器

顺序容器按元素插入顺序存储,提供对元素的顺序访问。

1. vector(动态数组)

说明:可变大小数组,支持快速随机访问,在尾部插入/删除元素高效,在其他位置插入/删除可能较慢。

方法演示

#include <vector> #include <iostream> int main() { // 构造 std::vector<int> v1; // 空vector std::vector<int> v2(5, 10); // 5个元素,每个为10 std::vector<int> v3 = {1, 2, 3, 4, 5}; // 初始化列表 std::vector<int> v4(v3.begin(), v3.end()); // 迭代器范围构造 // 元素访问 std::cout << v3[2] << std::endl; // 下标访问:3 std::cout << v3.at(2) << std::endl; // 带边界检查:3 std::cout << v3.front() << std::endl; // 首元素:1 std::cout << v3.back() << std::endl; // 尾元素:5 // 迭代器 for(auto it = v3.begin(); it != v3.end(); ++it) { std::cout << *it << " "; // 1 2 3 4 5 } // 容量 std::cout << "size: " << v3.size() << std::endl; // 元素数:5 std::cout << "capacity: " << v3.capacity() << std::endl; // 容量 std::cout << "empty: " << v3.empty() << std::endl; // 是否空:0 // 修改 v3.push_back(6); // 尾部添加 v3.pop_back(); // 删除尾部 v3.insert(v3.begin() + 2, 99); // 在位置2插入99 v3.erase(v3.begin() + 1); // 删除位置1的元素 v3.clear(); // 清空所有元素 // 内存管理 v3.reserve(100); // 预分配100个元素空间 v3.shrink_to_fit(); // 减少容量到适合当前大小 return 0; }

2. deque(双端队列)

说明:双端队列,支持在头尾快速插入/删除,随机访问效率略低于vector。

方法演示

#include <deque> #include <iostream> int main() { std::deque<int> dq = {1, 2, 3}; // 双端操作 dq.push_front(0); // 头部插入:{0,1,2,3} dq.push_back(4); // 尾部插入:{0,1,2,3,4} dq.pop_front(); // 删除头部:{1,2,3,4} dq.pop_back(); // 删除尾部:{1,2,3} // 随机访问 std::cout << dq[1] << std::endl; // 2 std::cout << dq.at(1) << std::endl; // 2 // 其他方法与vector类似 dq.insert(dq.begin() + 1, 99); // 插入 dq.erase(dq.begin() + 2); // 删除 return 0; }

3. list(双向链表)

说明:双向链表,在任何位置插入/删除都高效,不支持随机访问。

方法演示

#include <list> #include <iostream> int main() { std::list<int> lst = {1, 2, 3, 4, 5}; // 双向链表特有操作 lst.push_front(0); // 头部插入 lst.push_back(6); // 尾部插入 lst.pop_front(); // 删除头部 lst.pop_back(); // 删除尾部 // 链表操作 auto it = lst.begin(); std::advance(it, 2); // 移动迭代器到位置2 lst.insert(it, 99); // 在位置2插入99 lst.remove(3); // 删除所有值为3的元素 lst.unique(); // 删除连续重复值 lst.sort(); // 排序 lst.reverse(); // 反转 // 合并链表 std::list<int> lst2 = {7, 8, 9}; lst.merge(lst2); // 合并两个有序链表 // 拼接(转移元素) std::list<int> lst3 = {10, 11}; lst.splice(lst.begin(), lst3); // 将lst3元素拼接到lst开头 return 0; }

4. forward_list(单向链表)

说明:单向链表,比list更节省空间,只支持单向遍历。

方法演示

#include <forward_list> #include <iostream> int main() { std::forward_list<int> flst = {1, 2, 3, 4, 5}; // 单向链表操作 flst.push_front(0); // 只能头部插入 flst.pop_front(); // 只能删除头部 // 插入删除需要前驱迭代器 auto prev = flst.before_begin(); auto curr = flst.begin(); std::advance(prev, 2); // 获取前驱位置 flst.insert_after(prev, 99); // 在指定位置后插入 flst.erase_after(prev); // 删除指定位置后的元素 flst.remove(3); // 删除特定值 flst.unique(); // 删除连续重复 flst.sort(); // 排序 return 0; }

5. array(固定大小数组)

说明:固定大小数组,支持随机访问,大小在编译时确定。

方法演示

#include <array> #include <iostream> int main() { std::array<int, 5> arr = {1, 2, 3, 4, 5}; // 元素访问 std::cout << arr[2] << std::endl; // 3 std::cout << arr.at(2) << std::endl; // 3 std::cout << arr.front() << std::endl; // 1 std::cout << arr.back() << std::endl; // 5 // 迭代器 for(auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << " "; } // 容量(固定) std::cout << "size: " << arr.size() << std::endl; // 5 std::cout << "max_size: " << arr.max_size() << std::endl; // 5 // 填充 arr.fill(0); // 所有元素设为0 return 0; }

6. string(字符串)

说明:专门用于字符序列的容器,提供丰富的字符串操作。

方法演示

#include <string> #include <iostream> int main() { std::string str = "Hello"; // 构造 std::string s1("World"); std::string s2(5, 'A'); // "AAAAA" std::string s3(str, 1, 3); // "ell"(从位置1取3个字符) // 元素访问 std::cout << str[1] << std::endl; // 'e' std::cout << str.at(1) << std::endl; // 'e' std::cout << str.front() << std::endl; // 'H' std::cout << str.back() << std::endl; // 'o' // 修改 str.append(" World"); // "Hello World" str.push_back('!'); // "Hello World!" str.insert(5, " C++"); // "Hello C++ World!" str.erase(5, 4); // "Hello World!" str.replace(6, 5, "Earth"); // "Hello Earth!" // 查找 size_t pos = str.find("Earth"); // 6 pos = str.find('o'); // 4 pos = str.rfind('o'); // 从后向前找 // 子串 std::string sub = str.substr(6, 5); // "Earth" // 比较 int cmp = str.compare("Hello Earth!"); // 0表示相等 // 数值转换 std::string num_str = "123"; int num = std::stoi(num_str); // 字符串转整数 return 0; }

二、关联容器

关联容器按关键字存储元素,支持高效的关键字查找。

1. set(集合)

说明:有序集合,元素唯一,按值自动排序。

方法演示

#include <set> #include <iostream> int main() { std::set<int> s = {5, 2, 8, 1, 9}; // 插入 auto ret = s.insert(3); // 插入3 if(ret.second) { std::cout << "插入成功" << std::endl; } // 查找 auto it = s.find(5); // 查找元素5 if(it != s.end()) { std::cout << "找到元素: " << *it << std::endl; } // 计数 size_t cnt = s.count(5); // 返回1(存在)或0(不存在) // 范围查找 auto lower = s.lower_bound(3); // 第一个>=3的元素 auto upper = s.upper_bound(7); // 第一个>7的元素 auto range = s.equal_range(5); //等于5的范围 // 删除 s.erase(5); // 删除值为5的元素 s.erase(it); // 删除迭代器指向的元素 // 遍历(有序) for(const auto& elem : s) { std::cout << elem << " "; // 1 2 3 8 9 } return 0; }

2. multiset(多重集合)

说明:允许重复元素的set。

方法演示

#include <set> int main() { std::multiset<int> ms = {1, 2, 2, 3, 3, 3}; // 插入重复元素 ms.insert(2); // 可以插入重复值 // 计数 size_t cnt = ms.count(3); // 返回3(有3个值为3的元素) // 删除 ms.erase(2); // 删除所有值为2的元素 return 0; }

3. map(映射)

说明:键值对集合,键唯一,按键排序。

方法演示

#include <map> #include <iostream> int main() { std::map<std::string, int> m = { {"Alice", 25}, {"Bob", 30}, {"Charlie", 35} }; // 插入 m.insert({"David", 28}); // 插入键值对 m.emplace("Eve", 26); // 原地构造插入 // 访问(下标操作会创建不存在的键) std::cout << m["Alice"] << std::endl; // 25 m["Frank"] = 40; // 插入或修改 //查找 auto it = m.find("Bob"); if(it != m.end()) { std::cout << it->first << ": " << it->second << std::endl; } // 删除 m.erase("Charlie"); // 按键删除 // 遍历 for(const auto& [key, value] : m) { // C++17结构化绑定 std::cout << key << ": " << value << std::endl; } return 0; }

4. multimap(多重映射)

说明:允许重复键的map。

方法演示

#include <map> int main() { std::multimap<std::string, int> mm; // 插入重复键 mm.insert({"Alice", 25}); mm.insert({"Alice", 30}); // 允许重复键 // 查找所有相同键的值 auto range = mm.equal_range("Alice"); for(auto it = range.first; it != range.second; ++it) { std::cout << it->second << " "; // 25 30 } return 0; }

5. unordered_set(无序集合)

说明:基于哈希表的集合,元素无序但查找更快。

方法演示

#include <unordered_set> #include <iostream> int main() { std::unordered_set<int> us = {5, 2, 8, 1, 9}; // 插入 us.insert(3); // 查找 auto it = us.find(5); // 桶接口 std::cout << "桶数量: " << us.bucket_count() << std::endl; std::cout << "负载因子: " << us.load_factor() << std::endl; // 哈希策略 us.rehash(100); // 重新哈希 us.reserve(200); // 预留空间 return 0; }

6. unordered_multiset(无序多重集合)

说明:允许重复的无序集合。

7. unordered_map(无序映射)

说明:基于哈希表的键值对集合。

方法演示

#include <unordered_map> #include <iostream> int main() { std::unordered_map<std::string, int> um = { {"Alice", 25}, {"Bob", 30} }; // 插入访问 um["Charlie"] = 35; um.insert({"David", 28}); // 哈希相关 std::cout << "最大负载因子: " << um.max_load_factor() << std::endl; return 0; }

8. unordered_multimap(无序多重映射)

说明:允许重复键的无序映射。

三、容器适配器

容器适配器基于其他容器实现特定接口。

1. stack(栈)

说明:后进先出(LIFO)适配器,默认基于deque实现。

方法演示

#include <stack> #include <iostream> int main() { std::stack<int> stk; // 栈操作 stk.push(1); // 压栈 stk.push(2); stk.push(3); std::cout << "栈顶: " << stk.top() << std::endl; // 3 stk.pop(); // 弹出栈顶 std::cout << "大小: " << stk.size() << std::endl; // 2 std::cout << "是否空: " << stk.empty() << std::endl; // 0 return 0; }

2. queue(队列)

说明:先进先出(FIFO)适配器,默认基于deque实现。

方法演示

#include <queue> #include <iostream> int main() { std::queue<int> q; // 队列操作 q.push(1); // 入队 q.push(2); q.push(3); std::cout << "队首: " << q.front() << std::endl; // 1 std::cout << "队尾: " << q.back() << std::endl; // 3 q.pop(); // 出队 std::cout << "新队首: " << q.front() << std::endl; // 2 return 0; }

3. priority_queue(优先队列)

说明:元素按优先级出队,默认最大堆,基于vector实现。

方法演示

#include <queue> #include <iostream> int main() { // 最大堆(默认) std::priority_queue<int> max_pq; max_pq.push(3); max_pq.push(1); max_pq.push(4); max_pq.push(2); std::cout << "最大堆顶: " << max_pq.top() << std::endl; // 4 // 最小堆 std::priority_queue<int, std::vector<int>, std::greater<int>> min_pq; min_pq.push(3); min_pq.push(1); min_pq.push(4); min_pq.push(2); std::cout << "最小堆顶: " << min_pq.top() << std::endl; // 1 return 0; }

四、特殊容器

bitset(位集)

说明:固定大小的位序列,用于位级操作。

方法演示

#include <bitset> #include <iostream> int main() { std::bitset<8> b1("11001100"); // 二进制字符串构造 std::bitset<8> b2(0xFF); // 整数构造 // 位操作 b1.set(2); // 设置第2位为1 b1.reset(3); // 设置第3位为0 b1.flip(4); // 翻转第4位 // 测试 std::cout << "第2位: " << b1.test(2) << std::endl; // 1 std::cout << "所有位: " << b1.all() << std::endl; // 是否全1 std::cout << "任意位: " << b1.any() << std::endl; // 是否有1 std::cout << "没有位: " << b1.none() << std::endl; // 是否全0 // 计数 std::cout << "1的个数: " << b1.count() << std::endl; std::cout << "大小: " << b1.size() << std::endl; // 转换 unsigned long val = b1.to_ulong(); // 转无符号长整型 std::string str = b1.to_string(); // 转字符串 // 位运算 std::bitset<8> b3 = b1 & b2; // 与 std::bitset<8> b4 = b1 | b2; // 或 std::bitset<8> b5 = b1 ^ b2; // 异或 std::bitset<8> b6 = ~b1; // 非 return 0; }

五、容器通用操作

所有容器都支持的通用操作:

操作类型方法说明
类型别名value_type元素类型
reference元素引用类型
const_reference常量引用类型
iterator迭代器类型
const_iterator常量迭代器类型
size_type大小类型
构造函数C c默认构造
C c1(c2)拷贝构造
C c(beg, end)迭代器范围构造
C c{init_list}初始化列表构造
赋值c1 = c2拷贝赋值
c = {a,b,c}初始化列表赋值
c.assign(beg, end)迭代器范围赋值
c.assign(n, t)n个t值赋值
c.assign(init_list)初始化列表赋值
大小c.size()元素个数
c.max_size()可容纳最大元素数
c.empty()是否为空
添加删除c.insert(args)插入元素
c.emplace(args)原地构造插入
c.erase(args)删除元素
c.clear()删除所有元素
迭代器c.begin(), c.end()首尾迭代器
c.cbegin(), c.cend()常量迭代器
c.rbegin(), c.rend()反向迭代器
c.crbegin(), c.crend()常量反向迭代器
比较==, !=相等性比较
<, <=, >, >=关系比较(无序容器不支持)
交换swap(c1, c2)交换两个容器
c1.swap(c2)成员函数交换
// 通用操作示例 #include <vector> #include <list> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 3, 4, 5}; std::list<int> lst = {5, 4, 3, 2, 1}; // 类型别名使用 std::vector<int>::value_type elem = 10; // int std::vector<int>::iterator it; // 迭代器类型 // 赋值操作 std::vector<int> vec2; vec2.assign(vec.begin(), vec.end()); // 迭代器范围赋值 vec2.assign(5, 10); // 5个10 // 交换 std::swap(vec, vec2); // 交换两个容器 vec.swap(vec2); // 成员函数交换 // 比较 bool equal = (vec == vec2); // 比较是否相等 // 使用算法(需要包含<algorithm>) std::sort(vec.begin(), vec.end()); // 排序 auto found = std::find(vec.begin(), vec.end(), 3); // 查找 return 0; }

六、容器选择指南

容器类型适用场景时间复杂度(平均)
vector需要随机访问,主要在尾部插入删除访问O(1),尾部插入删除O(1),中间插入删除O(n)
deque需要在头尾快速插入删除,随机访问访问O(1),头尾插入删除O(1)
list需要频繁在任意位置插入删除,不需要随机访问插入删除O(1),访问O(n)
forward_list单向链表,内存受限场景同list但更省内存
array固定大小数组,栈上分配访问O(1),大小固定
string字符串处理同vector,额外字符串操作
set/map需要有序存储,快速查找查找、插入、删除O(log n)
multiset/multimap有序存储,允许重复键同set/map
unordered_set/unordered_map需要最快查找,不要求有序查找、插入、删除O(1)
stackLIFO(后进先出)场景基于底层容器
queueFIFO(先进先出)场景基于底层容器
priority_queue优先级调度插入O(log n),删除O(log n)
bitset位标志、位集操作访问O(1)

参考来源

  • 《C++ Primer》学习笔记(十一):关联容器
  • C++ 顺序容器--vector容器详解
  • cpp 09 字符(char)可以直接比较 | back( ) | auto 类型推导关键字
  • C++Primer学习一 (3容器)
  • C++ 容器详解
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/25 15:41:18

YOLOv8 AI自瞄系统:三步打造FPS游戏智能瞄准助手终极指南

YOLOv8 AI自瞄系统&#xff1a;三步打造FPS游戏智能瞄准助手终极指南 【免费下载链接】yolov8_aimbot Aim-bot based on AI for all FPS games 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8_aimbot 在竞争激烈的FPS游戏世界中&#xff0c;精准瞄准往往是决定胜负…

作者头像 李华
网站建设 2026/6/25 15:39:21

星谷云vs传统外贸代运营:社媒营销专业度的4个关键差异点

摘要&#xff1a;B2B出海企业在社媒营销中常面临专业度不足与转化难等痛点。星谷云作为一站式出海AI营销智能体矩阵平台&#xff0c;通过人机协同机制赋能制造业。本文从四个关键维度对比其与传统代运营的差异&#xff0c;解析如何构建从获客到成交的全链路体系&#xff0c;助力…

作者头像 李华
网站建设 2026/6/25 15:39:21

深入解析MSC8112 UART模块:从异步通信原理到寄存器配置与调试实践

1. 项目概述与核心价值在嵌入式系统开发中&#xff0c;UART&#xff08;通用异步收发传输器&#xff09;几乎是工程师们打交道最多的通信接口之一。无论是调试信息的打印、与传感器模块的交互&#xff0c;还是设备间的简单数据交换&#xff0c;UART都扮演着不可或缺的角色。它的…

作者头像 李华
网站建设 2026/6/25 15:37:39

MuleSoft+LangChain企业级AI编排实战:构建合规可审计的LLM流水线

1. 项目概述&#xff1a;当企业级集成遇上大模型&#xff0c;AI编排不是概念&#xff0c;是每天要跑通的流水线我在金融行业做系统集成落地已经十二年&#xff0c;从最早的ESB总线部署&#xff0c;到后来API网关大规模上线&#xff0c;再到最近三年深度参与多个AI中台建设&…

作者头像 李华
网站建设 2026/6/25 15:36:25

网页时光机的智慧解法:重新定义数字内容保存与恢复

网页时光机的智慧解法&#xff1a;重新定义数字内容保存与恢复 【免费下载链接】wayback-machine-webextension A web browser extension for Chrome, Firefox, Edge, and Safari 14. 项目地址: https://gitcode.com/gh_mirrors/wa/wayback-machine-webextension 你是否…

作者头像 李华