【问题标题】:How can we benefit from vs2010 hash_map's less?我们如何从 vs2010 hash_map 的 less 中受益?
【发布时间】:2012-09-20 14:04:27
【问题描述】:

如果您不知道 vs2010 实际上需要全排序,请参阅this,因此它需要的用户定义较少。

其中一个回答说可以进行二分搜索,但我不这么认为,这是因为

  1. 哈希函数应该是统一的,负载因子最好小于1,这意味着,在大多数情况下,每个哈希槽一个元素。即不需要二分查找。
  2. 很明显,由于定位合适,会减慢插入速度。

哈希映射如何从这种设计中受益?以及我们如何利用这种设计?

谢谢

【问题讨论】:

    标签: c++ data-structures stl


    【解决方案1】:

    哈希函数应该是统一的,负载因子最好小于1,这意味着,在大多数情况下,每个哈希槽一个元素。即不需要二分查找。

    每个哈希槽最多不会有一个元素。一些存储桶将不得不保留多个密钥。除非输入仅来自预先确定的受限值集(即完美散列),否则散列函数将不得不处理比它可以产生的输出更多的输入。会有碰撞;这在像这个一样通用的实现中是不可避免的。然而,好的散列函数应该产生分布良好的散列,这使得每个散列槽的元素数量保持在较低水平。

    很明显,由于定位合适,会减慢插入速度。

    假设一个好的散列函数和非退化输入(输入被设计成许多元素产生相同的散列),每个桶总是只有几个键。插入这样的二叉搜索树不会有那么大的成本,而且很少的成本可能会在其他地方带来好处(搜索可能比使用链表的实现更快)。并且在退化输入的情况下,哈希图会退化成二叉搜索树,这比简单的链表要好很多。

    【讨论】:

      【解决方案2】:

      您的问题在实践中基本上无关紧要,因为 C++ 现在提供 unordered_map 等,它们使用 Equal 谓词而不是小于比较器。

      但是,请考虑hash_map<string, ...>。显然,string 的值空间大于size_t 的值空间,因此对于任何散列函数,都会存在具有相同散列值的值,因此被放置在同一个桶中。在哈希表中的所有项目都放在同一个桶中的病态情况下,利用键之间的排序将提高访问、插入和删除的速度。

      请注意,在有序列表(或二叉树)上的搜索是 O(log n) 而不是 O(n)。

      【讨论】:

      • 如果我们不需要订购,我们可以在列表头部插入而不需要任何搜索。
      • @Chang no,因为需要判断key是否已经存在于bucket中。
      • 对,我最后的评论是错误的。但真正的实现仍然是使用循环而不是二分查找。因此我们需要 2 次比较来判断是否相等,并减慢插入速度。
      • @Chang 为什么你认为“真正的实现”没有使用二分搜索?
      • 对不起,我的意思是vs2010不使用二分搜索
      猜你喜欢
      • 2012-02-23
      • 1970-01-01
      • 2014-05-27
      • 2010-09-12
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      相关资源
      最近更新 更多