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/

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