std :: unordered_set如何分配存储桶以提供O1查找?

问题描述

如果哈希函数良好,则unordered_set应该提供O(1)查找时间。
每个存储桶都包含具有相同哈希值的项目。
假设我们的散列函数是理想的,并且完全没有冲突。
哈希值的范围可以从0到max(std :: size_t)。
如何在不为存储桶分配连续内存间隔的情况下组织unordered_set并提供O(1)查找?
我们不能分配连续的内存间隔,因为如果分配,那么我们仅将大量内存用于多个哈希值-例如0和1000000。
间的值根本没有用,但是我们为它们分配了内存。

解决方法

每个存储桶都包含具有相同哈希值的项目。

错了。每个存储桶“包含”具有相同值的项目:

hash(key)%当前存储桶数

让我们假设我们的哈希函数是理想的,并且完全不产生冲突。

在pre-mod空间中不存在冲突并不一定是理想的:重要的是将桶中的数目(如果有2的幂的桶计数,例如Visual C ++,则进行掩盖)掩盖后的冲突。

哈希值的范围可以从0到max(std :: size_t)。 如何在不为存储桶分配连续内存间隔的情况下组织unordered_set并提供O(1)查找?

当表具有最大的size()时,每个值/元素通常会有1到〜2个存储桶。您可以通过调用max_load_factor(float)来确定表何时调整大小,从而对此进行某种程度的自定义,但是您不能根据表的调整大小来进行自定义-这留给实现。 GCC通常会选择比当前大小大一倍的素数。 Visual C ++通常会使存储桶成倍增加。

我们不能分配连续的内存间隔,因为如果分配,那么我们仅将大量内存用于多个哈希值-例如0和1000000。 中间的值根本没有用,但是我们为它们分配了内存。

这将忽略哈希值到存储桶计数中的修改。 (它也忽略了稀疏数组的可行性,这是可行的,因为虚拟地址空间可能比支持它的物理RAM大得多,但这并不是哈希表的重点。)