不确定unordered_map的工作原理

时间:2016-04-17 05:59:28

标签: c++ unordered-map

我对unordered_map如何工作以及存储桶是什么以及如何管理这一点有点困惑。

this blog post开始,unordered_map是向量的向量。

我的问题是:

  • 假设桶是“内部”向量是正确的吗?
  • 因为每个桶(向量)可以包含多个元素,由哈希表上的哈希冲突(“外部”向量)给出,并且因为我们必须扫描这个内部向量(在线性时间内),所以它是正确的假设我们必须在密钥类型上定义相等的方法(对哈希运算符成瘾)以便在桶中找到密钥?
  • 默认情况下外部向量(哈希表)大小是多少?
  • 默认情况下内部矢量大小是多少?
  • 如果一个桶中的元素数量变得太大会发生什么?换句话说,当重新发生这种情况时会发生什么?

很抱歉这些问题,但我没有找到任何有关此结构如何工作的详细说明(例如在cppreference.com上)。

2 个答案:

答案 0 :(得分:5)

std::unordered_map是标准的C ++ hash table。它曾经在STL中被称为hash_map,但是当1998年许多STL接口被合并到C ++中时错过了船,到2011年,很多库都有自己的hash_map,C ++不得不选择另一个名字(我想“无序”是一个很好的选择;假设哈希表中的顺序是一个常见的错误来源。)

  

假设桶是“内部”向量是正确的吗?

不,它都是不正确的(与迭代器失效要求不兼容)和危险(在这个假设下你可能最终会减去指向同一个桶中元素的指针)。

在现实生活中,桶是链表; e.g。

  

假设我们必须在密钥类型上定义相等的方法(对哈希运算符成瘾)以便在桶中找到密钥是正确的吗?

是的,将密钥放在存储桶中正好是std::unordered_map的第4个模板参数(当然不需要在字面上调用“密钥类型上的相等方法”)

  

默认情况下外部向量(哈希表)大小是多少?

没有“外部载体”。默认构造的std::unordered_map的存储区数量为implementation-defined,您可以使用bucket_count进行查询。

  

默认情况下内部矢量大小是多少?

没有“内部载体”。任何给定存储桶的大小等于当前放置在存储桶中的元素数。您可以使用bucket_size

进行查询
  

如果一个存储桶中的元素数量变得太大会发生什么?换句话说,重新发生时会发生什么?

如果一个存储桶中的元素数量变得太大,则不会发生任何事情。但是,如果每个桶的平均元素数量(又名load_factor)超过max_load_factor,则会发生重新哈希(例如在insert上)

答案 1 :(得分:2)

这可以帮助您理解存储桶: http://www.cplusplus.com/reference/unordered_map/unordered_map/bucket_count/ http://www.cplusplus.com/reference/unordered_map/unordered_map/max_load_factor/

但总的来说,是的,桶就像内部向量。它需要一个等于运算符(或谓词)来区分具有相同散列的键。

桶的初始数量可能为0.可以通过rehash()或reserve()进行设置(它们的语义略有不同。)

http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/

在理想情况下,每个桶只有一个项目。您可以使用bucket_size来检查这一点。当载荷系数(总物品数与铲斗数)变高时,它会自动重新加载。

默认情况下,它的目标是1:1的负载系数。如果哈希函数是好的,这可能会持续到插入max_bucket_count项为止。

请记住,具体实施可能会有所不同。每个实现(例如来自不同平台或标准库)实际上只需要具有正确的语义。

如果这些答案对您的程序很重要,您可以按照我的描述查询这些值。如果您只是想绕过它,请在某些测试场景中查询它们,它可能会变得更加清晰。