如何在map和unordered_map之间选择?


83

假设我想使用字符串作为键来映射数据。什么容器应该怎么选择,map还是unordered_mapunordered_map占用更多的内存,所以让我们假设内存不是问题,而关注的是速度。

unordered_map通常应该给出O(1)的平均复杂度,而O(n)的最坏情况。在什么情况下会达到O(n)?什么时候map可以获得比更高的时间效率unordered_map?当n小时会发生吗?

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

如果我要遍历元素而不是每次都访问单个元素,我应该优先map吗?


3
您是否需要对映射中的项目进行排序?
某位程序员花了

哪个实现unordered_map使用更多的内存?
彼得·伍德

尽管哈希映射通常可以忽略不计,但您始终在哈希映射中具有内存开销。
ypnos

这是次要的一点,但是正如您提到的迭代,值得指出的是,如果在插入元素时进行迭代,则应优先使用map而不是unordered_map。
约翰·麦克法兰

Answers:


67

实际上,如果没有问题,unordered_map那么如果要访问单个元素,则总是更快。

最坏的情况是理论上的,并且限制了所有元素的单个哈希值。这没有实际意义。将unordered_map尽快慢,你必须在属于相同的散列至少数N个元素得到。这也没有实际意义。在某些特殊情况下,您可以使用特定的哈希算法来确保更均匀的分布。对于不共享特定模式的普通字符串,附带的通用哈希函数unordered_map也一样。

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


6
这个答案充其量是令人误解的。“ unordered_map总是比单元素访问总是更快”是不对的-我唯一能想到的总是如此,那就是它总是更快且渐近地摊销。在实践中,“摊销”是一个重要的警告:假设将其实现为某种哈希表,如果我正确地记住我的哈希表,那么当您通过插入元素来增长哈希表时,它将通过Ω(n)操作“打ic”每隔一段时间。这可能是也不可能是任何特定应用程序可以容忍的。
唐·哈奇

209
                       | 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| 

6
关于常见实现的评论:红黑树是一种平衡树(或更具体地说,是一种自平衡二进制搜索树)。
HelloGoodbye 2015年

2
重新平衡不超过log(n)
mtk

遍历所有元素呢?
Shashwat

7

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

如果您有这样一个糟糕的哈希函数,它会对所有输入搅动产生相同的哈希值(即产生冲突)...

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

始终是需求和数据种类/数量的问题。

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

这只是不同的结构。您最好根据典型的使用案例选择使用其中一种(考虑到您拥有的数据种类及其数量)

当n小时,hppaen吗?

在少量数据的情况下,一切都取决于特定的STL实现...因此,有时甚至是简单的向量/数组也可能比关联容器更快。


7

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

配置文件,然后决定。unordered_map通常更快,但因情况而异。

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

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

什么时候地图比unordered_map更有效率?n小时会幸福吗?

可能不是,但如果您确实在意,请对其进行概要分析。具有小尺寸的容器是您程序的瓶颈,这几乎是不可能的。无论如何,vector对于这种情况,简单的线性搜索可能会更快。


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.