map和unordered_map
1. map
map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STl容器),map会以键从小到大的顺序自动排序。
#include<iostram>
#include<map>
using namespace std;
int main()
{
map<char,int> mp;
mp['m']=20;
mp['r']=30;
mp['a']=40;
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
cout<<it->first<<' '<<it->second<<endl;
return 0;
}
//输出时,map会以键从小到大的顺序自动排序
a 40
m 20
r 30
头文件和定义
#include<map>
//字符串到整型的映射,必须使用string不能使用char数组。
//因为char数组作为数组是不能被作为键值的
map<typename1,typename2> mp;
//typename1为映射前的类型(键),typename2为映射后的类型(值)
元素访问
(1)对于一个定义为map<char,int> mp 的map来说,可以使用mp[‘c’]的方式直接访问。
(2)通过迭代器访问
//可以使用it->first来访问键,it->second来访问值
map<typename1,typename2>::iterator it;
基本操作
mp.find(key) //返回键为key的映射的迭代器
mp.erase(it) //it为需要删除的元素的迭代器
//例子
map<char,int>::iterator it=mp.find('b');
mp.erase(it);
mp.erase(key) //key为欲删除的映射的键
mp.erase(first,last)
mp.size() //获取mp中映射的对数
mp.clear() //用来清空m中的所有元素
用途
(1)需要建立字符串与整数之间映射的题目
(2)判断大整数或者其他类型数据是否存在的题目,map可以当bool数组使用
(3)字符串与字符串映射
注意:map的键和值是唯一的,如果一个键需要对应多个值,只能使用multimap.
2. unordered_map
头文件和定义
#include<unordered_map>
unordered_map<int,int> hashmap;
基本操作
find() 查找与指定键匹配的元素。
end() 刚超出序列末尾的位置
begin() 指定受控序列或存储桶的开头。
clear() 删除所有元素。
count(key) 查找与指定键匹配的元素数。
empty() 测试元素是否存在。
size() 对元素数进行计数。
移除指定位置处的元素。
iterator erase(const_iterator Where);
iterator erase(const_iterator First, const_iterator Last);
size_type erase(const key_type& Key);
使用示例
for (Mymap::const_iterator it = c1.begin();it != c1.end(); ++it)
cout << " [" << it->first << ", " << it->second << "]";
3. 相同
map
和unordered_map
这两种字典结构都是通过键值对(key-value)存储数据的,键(key)和值(value)的数据类型可以不同。且它们的key是唯一的。
4. 不同
头文件
#include<map>
#include<unordered_map>
实现的数据结构
- map是基于红黑树结构实现的,因此在map中的元素排列都是有序的。对map的增删改查,时间复杂度都为O(logn),n即为红黑树的高度。
- unordered_map是基于哈希表(也叫散列表)实现的。散列表使得unordered_map的插入和查询速度接近于O(1)(在没有冲突的情况下),但是其内部元素的排列顺序是无序的。
存储空间
unordered_map的散列空间会存在部分未被使用的位置,所以其内存效率不是100%的。而map的红黑树的内存效率接近于100%。
查找性能的稳定性
map的查找类似于平衡二叉树的查找,其性能十分稳定。例如在1M数据中查找一个元素,需要多少次比较呢?20次。map的查找次数几乎与存储数据的分布与大小无关。而unordered_map依赖于散列表,如果哈希函数映射的关键码出现的冲突过多,则最坏时间复杂度可以达到是O(n)。因此unordered_map的查找次数是与存储数据的分布与大小有密切关系的,它的效率是不稳定的。
使用场景
map元素有序,性能较为稳定。适用于元素要求有序、或者对单次查询时间较为敏感,必须保持查询性能的稳定性,比如实时应用。
unordered_map查询速度快O(1),但是元素无序、查询性能不稳定(最坏为O(n))。适用于要求查询速率快,对单次查询性能要求不敏感。
总结
:在需要元素有序性或者对单次查询性能要求较为敏感时使用map,其余情况下应使用unordered_map。进行算法编程的大部分情况下,都需要使用unordered_map而不是map。