如何在map和unordered_map之间进行选择?

时间:2012-12-10 10:58:51

标签: c++ dictionary data-structures stl unordered-map

假设我想用字符串作为键来映射数据。 我应该选择哪个容器mapunordered_mapunordered_map占用更多内存所以让我们假设内存不是问题,关注的是速度。

unordered_map通常应该给出O(1)的平均复杂度与O(n)的最坏情况。 在什么情况下它会到达O(n)? map何时获得的时间效率高于unordered_map?当n很小时会发生吗?

假设我将STL unordered_map与默认的haser Vs一起使用。地图。字符串是关键。

如果我要迭代元素而不是每次访问单个元素,我应该更喜欢map吗?

5 个答案:

答案 0 :(得分:181)

                       | map              | unordered_map
---------------------------------------------------------
element ordering       | strict weak      | n/a 
                       |                  |
common implementation  | balanced tree    | hash table
                       | or red-black tree|  
                       |                  |
search time            | log(n)           | O(1) if there are no hash collisions
                       |                  | Up to O(n) if there are hash collisions 
                       |                  | O(n) when hash is the same for any key
                       |                  |     
Insertion time         | log(n)+rebalance | Same as search
                       |                  | 
Deletion time          | log(n)+rebalance | Same as search
                       |                  | 
needs comparators      | only operator <  | only operator ==
                       |                  |
needs hash function    | no               | yes
                       |                  |
common use case        | when good hash is| In most other cases. 
                       | not possible or  | 
                       | too slow. Or when|
                       | order is required| 

答案 1 :(得分:56)

在实践中,如果内存没有问题,如果您想要单个元素访问,unordered_map总是更快。

最坏的情况是理论上的,并且绑定到所有元素的单个哈希。这不具有实际意义。只要至少有属于同一哈希的log N个元素,unordered_map就会变慢。这也没有实际意义。在某些特殊情况下,您可以使用特定的散列算法来确保更均匀的分布。对于不共享特定模式的普通字符串,unordered_map附带的通用散列函数也同样好。

如果要以排序的方式遍历地图(使用迭代器),则无法使用unordered_map。相反,map不仅允许这样做,而且还可以根据密钥的近似值为您提供地图中的下一个元素(请参阅lower_boundupper_bound方法)。< / p>

答案 2 :(得分:7)

  

在什么情况下会到达O(n)?

如果您有这样一个错误的哈希函数,它会为所有输入搅拌产生相同的哈希值(即产生碰撞)......

  

我应该选择哪个容器,map或unordered_map?

总是存在需求和类型/数量的问题。

  

地图什么时候比unordered_map更有时间效率?

这只是不同的结构。根据您的典型使用情况,你最好让chiose使用其中一个(考虑到你有什么样的数据及其数量)

  

当n很小时,它会起作用吗?

如果数据量很小,一切都取决于特定的STL实施...... 所以有时即使是普通的矢量/数组也可能比关联容器更快......

答案 3 :(得分:7)

  

我应该选择哪个容器,map或unordered_map? unordered_map占用更多内存所以让我们假设内存不是问题,关注的是速度。

简介然后决定。 unordered_map通常更快,但每种情况都有所不同。

  

在什么情况下它会到达O(n)?

当散列不好并且将一堆元素分配给相同的分档时。

  

地图什么时候比unordered_map更有时间效率?当n很小时,它会幸福吗?

可能不是,但如果你真的在乎的话可以说出来。拥有一个小尺寸的容器是你的程序的瓶颈似乎是不太可能的。无论如何,对于这种情况,使用线性搜索的简单vector可能会更快。


决定时最重要的是排序和缺少迭代器失效的要求。如果您需要,您几乎必须使用map。否则,unordered_map

答案 4 :(得分:0)

std::map 在平衡的 BST 中内部存储元素。因此,元素将按键的排序顺序存储。

std::unordered_map 使用哈希表存储元素。因此,元素不会以任何排序顺序存储。它们将按任意顺序存储。

内存使用:

unordered_map 的内存使用量比 map 多,因为 unordered_map 也需要空间来存储哈希表。

搜索元素的时间复杂度:

在 std::map 中搜索元素的时间复杂度为 O(log n)。即使在最坏的情况下也是 O(log n),因为元素在内部存储为平衡二叉搜索树 (BST)。

然而,在 std::unordered_map 中,搜索的最佳时间复杂度为 O(1)。其中,如果哈希码函数不好,那么最坏情况的复杂度可能是 O(n)