C++ STL map容器
一、存储:map是一种关联式容器,map容器存储的都是pair对象,也就是用pair类模板创建的键值对。各个键值对的键和值可以是任意数据类型,包括c++基本数据类型(int、double等),使用结构体或类自定义的类型。通常情况下,map容器中存储的各个键值对都用string字符串作为键的类型。
二、排序:在使用 map 容器存储多个键值对时,该容器会自动根据各键值对的键的大小,按照既定的规则进行排序。默认情况下,map 容器选用std::less<T>
排序规则(其中 T 表示键的数据类型),其会根据键的大小对所有键值对做升序排序。当然,根据实际情况的需要,我们可以手动指定 map 容器的排序规则,既可以选用 STL 标准库中提供的其它排序规则(比如std::greater<T>
),也可以自定义排序规则。
注意:使用 map 容器存储的各个键值对,键的值既不能重复也不能被修改。(unordered_map容器是 哈希表 的应用)
三、创建
- std::map<std::string, int>myMap
- std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} };
四、常用函数
begin()
end()
find(key):在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
empty()
size()
at() :找到 map 容器中 key 键对应的值,如果找不到,该函数会引发 out_of_range 异常。
insert() :向 map 容器中插入键值对。
erase() :删除 map 容器指定位置、指定键(key)值或者指定区域内的键值对。
swap() :交换 2 个 map 容器中存储的键值对,这意味着,操作的 2 个键值对的类型必须相同。
clear() :清空 map 容器中所有的键值对,即使 map 容器的 size() 为 0。
count(key):在当前 map 容器中,查找键为 key 的键值对的个数并返回。注意,由于 map 容器中各键值对的键的值是唯一的,因此该函数的返回值最大为 1。
五、遍历map
C++中访问容器需要使用迭代器,而非下标。
相异处:
1. 底层的数据结构不同
——map是基于红黑树结构实现的。红黑树是一种平衡二叉查找树的变体结构,它的左右子树的高度差有可能会大于 1。所以红黑树不是严格意义上的平衡二叉树AVL,但对之进行平衡的代价相对于AVL较低, 其平均统计性能要强于AVL。红黑树具有自动排序的功能,因此它使得map也具有按键(key)排序的功能,因此在map中的元素排列都是有序的。在map中,红黑树的每个节点就代表一个元素,因此实现对map的增删改查,也就是相当于对红黑树的操作。对于这些操作的复杂度都为O(logn),复杂度即为红黑树的高度。
——unordered_map是基于哈希表(也叫散列表)实现的。散列表是根据关键码值而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。散列表使得unordered_map的插入和查询速度接近于O(1)(在没有冲突的情况下),但是其内部元素的排列顺序是无序的。
2. 元素排列顺序不同
- map:基于红黑树,元素有序存储
- unordered_map:基于散列表,元素无序存储
3. 插入和查询的时间复杂度不同
- map:基于红黑树,复杂度与树高相同,即O(logn)。
- unordered_map:基于散列表,复杂度依赖于散列函数产生的冲突多少,但大多数情况下其复杂度接近于O(1)。
4. 效率及其稳定性不同
- 存储空间:unordered_map的散列空间会存在部分未被使用的位置,所以其内存效率不是100%的。而map的红黑树的内存效率接近于100%。
- 查找性能的稳定性:map的查找类似于平衡二叉树的查找,其性能十分稳定。例如在1M数据中查找一个元素,需要多少次比较呢?20次。map的查找次数几乎与存储数据的分布与大小无关。而unordered_map依赖于散列表,如果哈希函数映射的关键码出现的冲突过多,则最坏时间复杂度可以达到是O(n)。因此unordered_map的查找次数是与存储数据的分布与大小有密切关系的,它的效率是不稳定的。
5. 总结
- map:
- 优点:
- map元素有序(这是map最大的优点,其元素的有序性在很多应用中都会简化很多的操作);
- 其红黑树的结构使得map的很多操作都可在O(logn)下完成;
- map的各项性能较为稳定,与元素插入顺序无关;
- map支持范围查找。
- 缺点:
- 占用的空间大:红黑树的每一个节点需要保存其父节点位置、孩子节点位置及红/黑性质,因此每一个节点占用空间大。
- 查询平均时间不如unordered_map。
- 适用场景:
- 元素需要有序;
- 对于单次查询时间较为敏感,必须保持查询性能的稳定性,比如实时应用等等。
- 优点:
- unordered_map
- 优点:
- 查询速度快,平均性能接近于常数时间O(1);
- 缺点:
- 元素无序;
- unordered_map相对于map空间占用更大,且其利用率不高;
- 查询性能不太稳定,最坏时间复杂度可达到O(n)。
- 适用场景:
- 要求查找速率快,且对单次查询性能要求不敏感。
- 优点:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)