std::unordered_map 如何处理碰撞?

How does std::unordered_map handle collisions?

std::unordered_map 保证 O(1) 时间搜索,但它如何管理冲突?

Cppreference 索赔

Unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.

假设所有哈希码都相同的情况,内部如何处理冲突?

如果哈希码对每个键都是唯一的,我的假设就完全错误了。在那种情况下,如何在完全没有冲突的情况下创建唯一的哈希码?

std::unordered_map 的哈希函数采用什么方法来保证 O(1) 搜索?

它不能保证 O(1),它平均是 O(1)... 最坏的情况是当有很多碰撞时它可能是 O(n)。请参阅下面的 link,了解更多信息:

更新

由于问题已被编辑,现在专门询问 std::unordered_map 的碰撞,请查看以下答案:

I think we can conclude that all practical implementations of std::unordered_set (or unordered_map) almost certainly use collision chaining. While it might be (just barely) possible to meet the requirements using linear probing or double hashing, such an implementation seems to lose a great deal and gain nearly nothing in return.

您的 post 中有一处遗漏,这对理解至关重要:std::unordered_map 平均情况 O(1) 搜索。最多可能需要 O(n) 个地图中的元素来检索元素。

至于它使用哪个散列函数——这取决于用户。默认情况下它使用 std::hash.

关于冲突处理的散列函数的唯一要求是

Hash functions are only required to produce the same result for the same input within a single execution of a program; this allows salted hashes that prevent collision DoS attacks. (cppreference)

std::unordered_map guarantees O(1) time search, but how does it manage collision?

它使用开放寻址/独立链接,参见

Cppreference claims

Unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity.

Assuming a situation where all the Hash codes are same, how is the collision handled internally?

冲突的元素被添加到另一个容器中,该容器包含散列到该桶的所有值。该容器通常是一个链表,但没有什么可以阻止使用例如二叉树。

My assumption would be totally wrong if the hash code is unique to every key. In that case how is the unique hash code created where there are no collisions at all?

unordered_map 不需要也不期望做任何特殊的事情来避免碰撞。 (哈希码 “对每个键都是唯一的” 无论如何都不够,因为当哈希码被屏蔽或 mod-ed 到桶的数量时会产生冲突。 )

What approach does std::unordered_map's hash function take to guarantee O(1) search?

这就是你误解的症结所在。 unordered_map 当散列函数对跨存储桶的键进行散列处理时,性能为 O(1)。如果散列函数很差,或者已经被已知散列到同一个桶的密钥的恶意输入故意作为目标,它可能会降级到 O(n)。该标准不需要实施来防止这种情况发生,但用户可以提供加密哈希,在运行时从家族中选择哈希函数,或者以其他方式使恶意用户(或通常的类似输入)无法创建更多冲突。