C++ unordered_map原理

 

 

C++11推出了4个新的关联式容器:unordered_map,unordered_set, unordered_multimap, unordered_multiset, 即加入了unordered系列的容器。

这4个关联式容器与map,multimap,set,multiset功能基本类似,最主要就是底层结构不同,使用场景不容。

如果需要得到一个有序序列,使用红黑树系列的关联式容器,如果需要更高的查询效率,使用以哈希表为底层的关联式容器。 

 

unordered_map是c++11正式加入的对hashmap的官方实现。

 

unordered_map 原理

hashtable + bucket:

 unordered_map 内部采用 hashtable 的数据结构存储,每个特定的 key 会通过特定的哈希运算映射到一个特定的位置。

一般来说,hashtable 是可能存在冲突的,即不同的key值经过哈希运算之后得到相同的结果。解决方法是:在每个位置放一个桶,用于存放映射到此位置的元素,  当桶内数据量在8以内使用链表来实现桶,当数据量大于8 则自动转换为红黑树结构 也就是有序map的实现结构。


插入过程是:
1、得到 key;
2、通过 hash 函数得到 hash 值;
3、得到桶号(一般都为 hash 值对桶数求模);
4、存放 key 和 value 在桶内;

取值过程是:
1、得到 key
2、通过 hash 函数得到 hash 值
3、得到桶号(一般都为 hash 值对桶数求模)
4、比较桶的内部元素是否与 key 相等,若都不相等,则没有找到。
5、取出相等的记录的 value。

 

定位时间复杂度为O(1),同 数组 或者vector之类的连续内存存储结构。

 

查询一个key最差的时间复杂度是:

首先进行一次hash运算找到桶的位置,然后使用链表或者红黑树来继续查找(所有元素在同一个桶里,其他桶位全为空,这个桶位其实就是一个数组下面挂红黑树也就是挂了一个map的结构),所以时间复杂度是计算hash+O(1)+O(lgn)。

但是这几乎是不可能的。在一个设计正常的hash函数里结果应该是偏向平均的,至少设计方向是偏向平均的。这样时间复杂度就是计算hash+O(1)+O(lg(n/m)), m是桶数(通常设计为2的n次方)。根据时间复杂度的取值规则时间复杂度为O(lgn/m)。

无论是查找效率还是插入、删除效率unordered_map都优于map。所以在对数据不要求有序的情况下,尽量使unordered_map。除非你对数据要求有序才去使用map.


Ref:

https://www.jianshu.com/p/56bb01df8ac7

https://www.cnblogs.com/tp-16b/p/9156810.html

https://blog.csdn.net/baihebeijixing/article/details/104349309/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章