标准::unordered_multiset插入的复杂性

Complexity of std::unordered_multiset insert

本文关键字:复杂性 插入 unordered 标准 multiset      更新时间:2023-10-16

为什么插入std::unordered_multiset的最坏情况复杂度是线性的?我理解为什么std::unordered_set是这种情况(您必须检查插入的值是否不在集合中),但对于多集我不明白。我错过了一些明显的东西吗?

std::unordered_multiset::insert()的最坏情况复杂度是线性的,因为:

    支持
  • 非唯一键的无序关联容器称为支持等效键。 迭代这些容器时,具有等效键的元素在迭代中彼此相邻,形成等效键组
  • 迭代器函数需要恒定的摊销时间。

例如,考虑将 51313插入到具有4存储桶的unordered_multiset中,并且unordered_multiset::key_eq(5, 13)返回false的情况。 在这种情况下,unordered_multiset::hash_function(5)513 返回不同的哈希代码。 尽管具有不同的哈希代码,但这些元素仍可能插入到同一存储桶中。 如果整数的哈希函数返回整数本身,并且存储桶索引是哈希代码模数的结果,则

  • 元素 5 被散列到 5 ,并且使用4桶,它被放置在桶1中。
  • 元素 13 被散列到13,并且通过4桶,它也被放入桶1中。

虽然unordered_set::insert()检查以防止插入过程中出现重复项,但unordered_multiset::insert()标识在何处插入元素以进行等效键分组。 在最坏的情况下,存储桶在插入最终13时包含[5, 13],并且在迭代所有元素时,存储桶包含[5, 13, 13] 。 当对所有元素进行迭代时,复杂性在size()中是线性的。

值得注意的是,在unordered_multiset::insert()期间可能会发生重新散列,并且unordered_multiset::rehash()被指定为具有复杂度,平均情况为线性size(),最坏情况是二次的。 在重新哈希期间,原始哈希表中的所有元素都将迭代并插入到新的哈希表中。 由于迭代在size()中具有线性复杂度,并且如上所述,每个插入在size()中都有一个更差情况线性,因此得到的最坏情况是O(size()*size())