C++ 无序映射的实现

C++ 无序映射的实现,c++,hash,unordered-map,C++,Hash,Unordered Map,我试图理解无序映射和散列。据我所知,无序映射内部有一个哈希函数,它接受一个类型为T的对象,并返回一个int,然后使用int作为内部数组的索引。它在数组位置使用一个类型为T的对象列表,这样,如果spot中已经存在某个对象,则会在列表中插入其他对象 从概念上讲,使用集合而不是列表会提高效率吗? (也许二进制搜索和有序的集合有助于获得列表) 或者是一个向量而不是列表? (可能随机访问有助于列表。)数据类型应该无关紧要,因为在大多数情况下,散列索引处的容器只包含零或一个元素。如果经常有很多元素,哈希映射

我试图理解无序映射和散列。据我所知,无序映射内部有一个哈希函数,它接受一个类型为T的对象,并返回一个int,然后使用int作为内部数组的索引。它在数组位置使用一个类型为T的对象列表,这样,如果spot中已经存在某个对象,则会在列表中插入其他对象

从概念上讲,使用集合而不是列表会提高效率吗?
(也许二进制搜索和有序的集合有助于获得列表)

或者是一个向量而不是列表?
(可能随机访问有助于列表。)

数据类型应该无关紧要,因为在大多数情况下,散列索引处的容器只包含零或一个元素。如果经常有很多元素,哈希映射的性能会下降。解决方法是调整初始数组的大小,而
std::unordered_map
本身就是这样做的。但是,如果您有一个错误的哈希函数,它会导致许多哈希冲突,那么切换哈希函数对于正确的操作是必要的。

如果在同一个bucket中经常有很多冲突,那么使用集合比使用列表更有效,事实上,一些Java哈希表实现为此采用了集合。向量不能用于
std::unordered_map
std::unordered_set
实现,因为它们需要在超出其容量时重新分配到不同的内存区域,而标准要求无序容器中的元素永远不会被容器上的其他操作移动

也就是说,哈希表的本质是——使用高质量的哈希函数——在特定存储桶中碰撞的元素数量的统计分布只与负载因子有关。如果您不能相信冲突不会失控,那么可能不应该使用该哈希函数


一些细节:标准库无序容器的默认值(与的比率)为1.0,使用强伪随机散列函数,它们将有1/e~=36.8%的桶为空,有一个元素的桶为空,有两个元素的桶为空,有一半的桶为空(~18.4%),三分之一的桶为空,有三个元素(~6.13%),四分之一的桶为空,有四个元素(~1.53%),其中五分之一含有5种元素(~0.3%),六分之一含有6种元素(~0.05%)。正如您所希望看到的,必须搜索许多元素的情况非常罕见(即使在哈希表处于其最大负载因子的最坏情况下),因此列表方法通常是足够的。

此方法关闭的副本没有解决此处的问题,即“是否使用集合[或向量]而不是链接列表?”[在每个桶中]提高效率?”。