0

我正在查看这个StackOverflow 答案以更好地理解散列并看到以下内容(关于我们需要在恒定时间内获取存储桶大小的事实):

如果您使用线性探测或双散列等方法,找到所有散列到相同值的项目意味着您需要对值进行散列,然后遍历表中非空项目的“链”以查找其中有多少哈希到相同的值。但是,这与散列到相同值的项目数量不是线性的——它与散列到相同或冲突值的项目数量成线性关系。

这意味着它“与散列到相同或冲突值的项目数量呈线性关系”是什么意思?它对哈希表中的项目总数不是线性的吗,因为它可能需要在线性探测期间遍历每个值?我不明白为什么它只需要通过那些相撞的。

例如,如果我在散列表上使用线性探测(步长 1)并且我有不同的键(不冲突,所有散列到唯一值)映射到奇数索引槽1,3,5,7,9.....然后,我想插入许多所有散列的键到 2,所以我用这些键填充了所有偶数索引点。如果我想知道有多少键哈希为 2,我不需要遍历整个哈希表吗?但我不只是遍历散列到相同或冲突值的项目,因为奇数索引槽没有冲突。

4

1 回答 1

1

哈希表在概念上类似于链表的数组(表)(表中的存储桶)。不同之处在于您管理和访问该数组的方式:使用函数生成一个用于计算数组索引的数字。

一旦将两个元素放在同一个桶中(相同的计算值,即碰撞),那么问题就变成了在列表中的搜索。列表中的元素数量希望低于哈希表中的总元素(意味着其他元素存在于其他桶中)。

但是,您将跳过该段中的重要介绍:

如果您使用线性探测或双重哈希之类的方法,找到所有哈希到相同值的项目意味着您需要对值进行哈希处理,然后遍历表中非空项目的“链”以找出其中有多少哈希到相同的值。但是,这与散列到相同值的项目数量不是线性的——它与散列到相同或冲突值的项目数量是线性的

线性探测是哈希表的一种不同实现,其中您不使用任何列表(链)进行碰撞。相反,您只需找到数组中最近的可用点,从预期位置开始并向前。数组填充的越多,发现下一个位置也被使用的机会就越大,所以你只需要继续搜索。这些位置由散列到相同或冲突值的项目使用,尽管您永远不会(而且您并不真正关心)这两种情况中的哪一种,除非您在那里明确地看到现有元素的散列。

这个 CppCon 演示视频对哈希表进行了很好的介绍和深入分析。

于 2018-04-16T08:34:17.540 回答