Unordered Map
Basic Usage Detail and Example
Unordered map是C++11新出的特性,它提供了一种map的实现机制,可以存储键值对。Unordered map内部实现了哈希函数,当我们插入一个新的元素时:
- 首先对key做哈希函数处理,然后选择一个合适的bucket;
- 比较该bucket下的key是否重复;
- 在不重复的情况下,添加该元素到bucket中;
因此Unordered map时无序的,并且其搜索元素的时间复杂度为O(1)。
Different Ways to initialize an unordered_map
unordered map提供了三种不同的重载构造器:
- 通过initializer_list初始化
1 | std::unordered_map<std::string, int> wordMap({ |
- 使用iterable range初始化
1 | std::unordered_map<std::string, int> wordMap_2(wordMap.begin(), wordMap.end()); |
- 使用另一个unordered_map初始化
1 | std::unordered_map<std::string, int> wordMap_3(wordMap); |
Searching in unordered_map
unordered_map提供了一个成员函数find(),改函数接受一个key作为参数,在找到元素的时候就会返回一个相对应的迭代器,否则会返回map的尾部迭代器。
1 | iterator find ( const key_type& k ); |
Different ways to insert elements in an unordered_map
unordered_map提供了多种insert()成员函数的重载版本,我们来一一讨论:
- 通过initializer_list插入多个元素;
1 | void insert ( initializer_list<value_type> il ); |
这种插入方式有一个缺点,因为insert()返回的是void类型,因此在添加重复key的元素时,用户无法确定插入是否成功。
- unordered_map提供了一个重载版本,它接受std::pair of key – value 作为参数,并返回一对迭代器和bool变量,通过该bool变量我们就可以判断插入是否成功;
1 | pair<iterator,bool> insert ( const value_type& val ); |
Erasing an element
要想从unordered_map中删除元素,其提供了两种方式,如下:
- 通过提供key类型,即可删除该元素;
1 | size_type erase ( const key_type& k ); |
它的返回值为0或1,对应的是被删除的元素数量
- 通过迭代器删除元素;
1 | iterator erase ( const_iterator pos ); |
改函数接收一个迭代器对象,并删除其对应的元素。在删除1,返回指向被删除元素对应的下一个元素的迭代器。因此需要注意的是,在遍历迭代器的过程中删除元素,其返回值是一个有效的迭代器,为被删除元素的下一个。
std::map vs std::unordered_map
本节主要讨论std::map与std::unordered_map的区别,它们虽然都是存储键值对与实现了有效插入、搜索和删除操作,但有着以下的不同:
- 内部实现:与std::unordered_map不同,std::map是通过二叉搜索树存储元素的,因此它能通过key进行排序;
- 内存使用:std::unordered_map需要更多的内存来存储哈希表;
- 搜索的时间复杂度:由于std::map是树的结构,因此其时间复杂度为O(log n),而std::unordered_map最好的时间复杂度是O(1),最坏的情况是O(n),即所有元素在同一个bucket;
- 自定义key的使用方法:使用自定义key时,对于std::map来说,需要重载<操作符或者传入外部的comparator比较器,对于std::unordered_map则需要提供std::hash<K>,同时我们还需要重载==操作符;