news 2026/4/15 11:07:36

c++遍历容器(vector、list、set、map

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c++遍历容器(vector、list、set、map

遍历vector

1.基于范围的 for 循环(C++11 起推荐使用)

#include <vector> #include <iostream> std::vector<int> vec = {1, 2, 3, 4, 5}; for (const auto& element : vec) { std::cout << element << " "; }
  • 使用const auto&避免不必要的拷贝(尤其对大型对象有用)。
  • 如果你需要修改元素,可以去掉const或使用auto&

2.使用迭代器

for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; }

或者使用const_iterator(只读):

for (auto it = vec.cbegin(); it != vec.cend(); ++it) { std::cout << *it << " "; }

3.传统下标循环

for (size_t i = 0; i < vec.size(); ++i) { std::cout << vec[i] << " "; }
  • 注意:size()返回的是size_t(无符号类型),避免与有符号整数比较产生警告。

4.使用 std::for_each(函数式风格)

#include <algorithm> std::for_each(vec.begin(), vec.end(), [](int n) { std::cout << n << " "; });

输出两层循环的vector

方法 1:基于范围的 for 循环(推荐)

for (const auto& row : matrix) { for (const auto& elem : row) { std::cout << elem << " "; } std::cout << "\n"; // 每行结束后换行 }

方法 2:传统下标循环

for (size_t i = 0; i < matrix.size(); ++i) { for (size_t j = 0; j < matrix[i].size(); ++j) { std::cout << matrix[i][j] << " "; } std::cout << "\n"; }

⚠️ 注意:使用size_t避免有符号/无符号比较警告。

方法 3:迭代器方式

for (auto row_it = matrix.begin(); row_it != matrix.end(); ++row_it) { for (auto elem_it = row_it->begin(); elem_it != row_it->end(); ++elem_it) { std::cout << *elem_it << " "; } std::cout << "\n"; }

遍历deque

在 C++ 中,std::deque(双端队列)是一个支持在两端高效插入/删除、同时支持随机访问的顺序容器。遍历deque的方式非常灵活,几乎和vector一样丰富。

方法 1:基于范围的 for 循环(C++11 起,推荐)

#include <iostream> #include <deque> std::deque<int> dq = {10, 20, 30, 40}; for (const auto& elem : dq) { std::cout << elem << " "; } // 输出: 10 20 30 40

如果需要修改元素:

for (auto& elem : dq) { elem *= 2; // 所有元素翻倍 }

方法 2:使用下标(随机访问)

for (size_t i = 0; i < dq.size(); ++i) { std::cout << dq[i] << " "; // 或 dq.at(i) }

方法 3:使用迭代器(正向)

// 普通迭代器 for (auto it = dq.begin(); it != dq.end(); ++it) { std::cout << *it << " "; } // 只读迭代器(推荐用于只读场景) for (auto it = dq.cbegin(); it != dq.cend(); ++it) { std::cout << *it << " "; }

方法 4:反向遍历(从尾到头)

// 基于范围(C++17 不支持直接反向范围 for,需用迭代器) for (auto rit = dq.rbegin(); rit != dq.rend(); ++rit) { std::cout << *rit << " "; } // 输出: 40 30 20 10

方法 5:使用 std::for_each + lambda

#include <algorithm> std::for_each(dq.begin(), dq.end(), [](int n) { std::cout << n << " "; });

⚠️ deque 遍历注意事项

特性说明
✅ 支持随机访问可用dq[i]dq.at(i),时间复杂度 O(1)
✅ 支持双向迭代++it/--it都高效
✅ 迭代器可能失效仅当在头部或尾部扩容时,所有迭代器可能失效(与vector类似,但比list更敏感)
🔄 内存非连续虽然支持随机访问,但底层是分段连续存储,缓存性能略低于vector

遍历set

在 C++ 中,std::set是一个有序、唯一的关联容器(通常基于红黑树实现),遍历方式与vector类似,但由于其元素是const 的(不可修改),有一些细节需要注意。

1.基于范围的 for 循环(推荐,C++11 起)

#include <iostream> #include <set> std::set<int> mySet = {3, 1, 4, 1, 5}; for (const auto& elem : mySet) { std::cout << elem << " "; // 输出: 1 3 4 5 }
  • 元素自动按升序排列(默认使用std::less)。
  • 不能通过遍历修改元素(因为set中的 key 是 const 的),所以用const auto&是安全且高效的。

2.使用迭代器

for (auto it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *it << " "; }

或只读迭代器(更明确):

for (auto it = mySet.cbegin(); it != mySet.cend(); ++it) { std::cout << *it << " "; }

3.使用 std::for_each + lambda

#include <algorithm> std::for_each(mySet.begin(), mySet.end(), [](const int& n) { std::cout << n << " "; });
  • std::set不支持下标访问(如mySet[i]是非法的)。
  • 遍历时元素自动排序(除非你自定义了比较函数)。
  • 所有遍历方式都是只读的——这是由set的设计决定的(修改 key 会破坏内部结构)。

遍历list

在 C++ 中,std::list是一个双向链表容器,支持高效的插入和删除操作(但不支持随机访问)。遍历std::list的方式与其他 STL 容器类似,但由于其底层是链表结构,不能使用下标(如list[i]

注意事项

特性说明
❌ 不支持下标访问mylist[0]是非法的,编译会报错
✅ 支持修改元素通过非 const 引用或迭代器可修改值
✅ 迭代器稳定插入/删除(除被删元素外)不会使其他迭代器失效
🔄 双向遍历支持++it--it,以及rbegin()/rend()

方法 1:基于范围的 for 循环(C++11 起,推荐)

#include <iostream> #include <list> std::list<int> mylist = {10, 20, 30, 40}; for (const auto& elem : mylist) { std::cout << elem << " "; } // 输出: 10 20 30 40

如果需要修改元素,可用auto&

for (auto& elem : mylist) { elem *= 2; // 所有元素翻倍 }

方法 2:使用迭代器

// 正向遍历 for (auto it = mylist.begin(); it != mylist.end(); ++it) { std::cout << *it << " "; } // 只读遍历(更安全) for (auto it = mylist.cbegin(); it != mylist.cend(); ++it) { std::cout << *it << " "; }

方法 3:反向遍历(从尾到头)

for (auto rit = mylist.rbegin(); rit != mylist.rend(); ++rit) { std::cout << *rit << " "; } // 输出: 40 30 20 10

方法 4:使用 std::for_each + lambda

#include <algorithm> std::for_each(mylist.begin(), mylist.end(), [](int n) { std::cout << n << " "; });

性能提示

  • std::list遍历速度通常比std::vector(因为内存不连续,缓存不友好)。
  • 如果只是顺序读取且不需要频繁中间插入/删除,优先考虑vectordeque

遍历map

特性说明
自动排序std::map内部基于红黑树,遍历时按键升序输出
key 不可修改遍历时pair.firstconst,不能修改 key
value 可修改可通过pair.second = newValue修改值(若用非 const 引用)
无重复 key插入相同 key 会覆盖旧值

在 C++ 中,std::map是一个有序的键值对(key-value)关联容器,每个元素是一个std::pair<const Key, Value>。遍历map的结果会按键的升序自动排序(默认使用std::less<Key>)。

方法 1:基于范围的 for 循环(C++11 起,推荐)

#include <iostream> #include <map> #include <string> std::map<std::string, int> scores = { {"Alice", 95}, {"Bob", 87}, {"Charlie", 92} }; for (const auto& pair : scores) { std::cout << pair.first << " => " << pair.second << "\n"; }

或者使用结构化绑定(C++17 起更清晰):

for (const auto& [key, value] : scores) { std::cout << key << " => " << value << "\n"; }

方法 2:使用迭代器

for (auto it = scores.begin(); it != scores.end(); ++it) { std::cout << it->first << " => " << it->second << "\n"; }

方法 3:使用 std::for_each + lambda

#include <algorithm> std::for_each(scores.begin(), scores.end(), [](const auto& p) { std::cout << p.first << " => " << p.second << "\n"; });

一、基本特性总览

容器底层结构是否有序元素是否唯一支持随机访问插入/删除效率(典型位置)是否支持下标[]
vector动态数组✅ O(1)尾部:O(1)
中间/头部:O(n)
deque分段连续数组✅ O(1)两端:O(1)
中间:O(n)
list双向链表任意位置:O(1)(需迭代到位置)
set红黑树(平衡 BST)✅(按键)任意位置:O(log n)
map红黑树✅(按键)✅(key 唯一)任意位置:O(log n)✅(map[key],但会插入默认值)

遍历方式对比

容器范围 for下标[]迭代器反向遍历遍历时修改元素
vector✅(非 const)
deque
list
set❌(key 是 const)
map❌(不能用于遍历)✅(可改 value,不能改 key)
性能对比(时间复杂度)
操作vectordequelistset/map
尾部插入O(1) amortizedO(1)O(1)O(log n)
头部插入O(n)O(1)O(1)O(log n)
中间插入O(n)O(n)O(1)*O(log n)
随机访问O(1)O(1)O(n)
查找(按值)O(n)O(n)O(n)O(log n)
删除(已知位置)O(n)O(n)O(1)O(log n)
内存局部性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

使用场景建议

容器推荐使用场景
vector- 需要频繁随机访问
- 数据量固定或主要在尾部增删
- 对缓存友好(高性能循环)
deque- 需要在两端高效插入/删除(如队列、滑动窗口)
- 不需要中间插入
list- 需要在任意位置频繁插入/删除(且已有迭代器)
- 不关心随机访问和内存连续性
- 实现 LRU 缓存等
set- 需要自动去重 + 自动排序
- 快速判断元素是否存在
map- 需要键值映射 + 自动按键排序
- 快速通过 key 查找 value

完整容器列表

容器类型是否有序允许重复底层实现头文件
std::set✅ 是❌ 否红黑树(平衡二叉搜索树)<set>
std::multiset✅ 是✅ 是红黑树<set>
std::unordered_set❌ 否❌ 否哈希表 + 链地址法(或开放寻址)<unordered_set>
std::unordered_multiset❌ 否✅ 是哈希表<unordered_set>
std::map✅ 是❌ 否(key 唯一)红黑树<map>
std::multimap✅ 是✅ 是(相同 key 可多次出现)红黑树<map>
std::unordered_map❌ 否❌ 否(key 唯一)哈希表<unordered_map>
std::unordered_multimap❌ 否✅ 是哈希表<unordered_map>

所有unordered_*容器要求key 类型支持哈希(即提供std::hash<Key>特化),否则需自定义哈希函数。


时间复杂度对比(平均 / 最坏)

操作set/map
(红黑树)
multiset/multimapunordered_*
(哈希表)
插入O(log n)O(log n)平均 O(1)
最坏 O(n)(哈希冲突严重或 rehash)
删除O(log n)O(log n)平均 O(1)
最坏 O(n)
查找(by key)O(log n)O(log n)平均 O(1)
最坏 O(n)
范围查询
(如lower_bound
✅ O(log n)❌(不支持有序范围)
遍历全部元素O(n),有序O(n),有序O(n),无序
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/27 10:08:44

RMBG-2.0效果对比:与传统抠图工具的全面评测

RMBG-2.0效果对比&#xff1a;与传统抠图工具的全面评测 1. 为什么这次抠图体验让我重新打开了修图软件 上周给客户做电商主图&#xff0c;一张模特穿新季连衣裙的照片卡了我整整两小时。发丝边缘毛躁、薄纱材质半透明、背景是带纹理的浅灰墙纸——用Photoshop钢笔工具抠了三…

作者头像 李华
网站建设 2026/4/14 5:52:55

开源串流工具低延迟优化指南:跨设备高清流畅体验实战

开源串流工具低延迟优化指南&#xff1a;跨设备高清流畅体验实战 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器&#xff0c;支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshin…

作者头像 李华
网站建设 2026/4/16 9:04:03

StructBERT中文文本分类:快速上手与实战应用

StructBERT中文文本分类&#xff1a;快速上手与实战应用 1. 为什么你需要一个“不用训练”的文本分类器&#xff1f; 你有没有遇到过这样的情况&#xff1a; 客服团队每天收到几百条用户反馈&#xff0c;但没人来标注“这是咨询还是投诉”&#xff1b;运营同事临时要对一批新…

作者头像 李华
网站建设 2026/4/3 3:51:33

从草图到代码:Doubao-Seed-Code如何用视觉理解重构Obsidian插件UI设计

视觉驱动开发&#xff1a;Doubao-Seed-Code如何重塑Obsidian插件设计范式 当设计稿与代码之间的鸿沟被AI瞬间弥合&#xff0c;一场关于生产力革命的序幕正在拉开。在Obsidian插件开发领域&#xff0c;Doubao-Seed-Code带来的视觉理解能力正在颠覆传统的UI开发流程。这款支持原生…

作者头像 李华
网站建设 2026/4/16 0:42:51

mT5分类增强版中文-base效果展示:中文电商搜索Query多样性增强

mT5分类增强版中文-base效果展示&#xff1a;中文电商搜索Query多样性增强 1. 这不是普通改写&#xff0c;是搜索Query的“语义扩容术” 你有没有遇到过这样的问题&#xff1a;用户搜“苹果手机壳”&#xff0c;结果只返回带“苹果”和“手机壳”的商品&#xff1b;但其实“i…

作者头像 李华
网站建设 2026/4/15 20:41:42

AI生成网站工具盘点:哪款最适合企业官网?

随着人工智能技术的快速发展&#xff0c;AI生成网站 已经从概念走向实用&#xff0c;成为企业提升品牌形象与用户体验的重要利器。相比传统建站方式&#xff0c;AI生成网站工具能大幅节省时间和成本&#xff0c;同时输出更符合用户需求的设计与内容。本文将盘点几款主流 AI网站…

作者头像 李华