轉自https://blog.csdn.net/liumou111/article/details/49252645
在之前使用STL時,經常混淆的幾個數據結構,特別是做Leetcode的題目時,對於使用哪一個map,一直沒有太明確的概念,事實上,三個容器,有着比較大的區別.
1. map
內部數據的組織,基於紅黑樹實現,紅黑樹具有自動排序的功能,因此map內部所有的數據,在任何時候,都是有序的。
2. hash_map
基於哈希表,數據插入和查找的時間復雜度很低,幾乎是常數時間,而代價是消耗比較多的內存。底層實現上,使用一個下標范圍比較大的數組來存儲元素,形成很多的桶,利用hash函數對key進行映射到不同區域進行保存。
- 插入操作:得到key -> 通過hash函數得到hash值 -> 得到桶號(hash值對桶數求模) -> 存放key和value在桶內
- 取值過程:得到key -> 通過hash函數得到hash值 -> 得到桶號(hash值對桶數求模) -> 比較桶內元素與key是否相等 -> 取出相等紀錄的value
- 當每個桶內只有一個元素時,查找時只進行一次比較,當很多桶都沒有值時,查詢更快。
- 用戶可以指定自己的hash函數與比較函數。
3. unordered_map
C++ 11標准中加入了unordered系列的容器。unordered_map記錄元素的hash值,根據hash值判斷元素是否相同。map相當於java中的TreeMap,unordered_map相當於HashMap。無論從查找、插入上來說,unordered_map的效率都優於hash_map,更優於map;而空間復雜度方面,hash_map最低,unordered_map次之,map最大。
對於STL里的map容器,count方法與find方法,都可以用來判斷一個key是否出現,count統計的是key出現的次數,因此只能為0/1,而find基於迭代器實現,以mp.end()判斷是否找到要求的key。
下面測試說明了速度之間的比較:
map類型 | 插入速度 | 插入和查找速度 |
---|---|---|
hashmap | 0m0.123s | 0m0.369s |
map | 0m0.190s | 0m0.681s |
unordered_map | 0m0.123s | 0m0.315s |
- 為什么要使用unordered_map代替hash_map?
- 因為標准化的推進,unordered_map原來屬於boost分支和std::tr1中,而hash_map屬於非標准容器。
- 另外,使用之后,感覺速度和hash_map差不多,但是支持string做key,也可以使用復雜的對象作為key。
- gxx需要添加編譯選項:--std=gnu++0x或者--std=c++0x