代码之家  ›  专栏  ›  技术社区  ›  rb612

哈希表在相同或冲突值上是如何线性的?

  •  0
  • rb612  · 技术社区  · 6 年前

    我在看 this StackOverflow回答了如何更好地理解哈希,并看到了以下内容(关于我们需要在恒定时间内获取桶大小的事实):

    如果使用线性探测或双重散列,查找散列到相同值的所有项目意味着需要对值进行散列,然后遍历表中非空项目的“链”,以查找散列到相同值的项目数量。这与散列到相同值的项数不是线性的,而是与散列到相同值或冲突值的项数是线性的。

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

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Jorge Bellon    6 年前

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

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

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

    如果你使用 线性探测或双哈希 ,查找散列到相同值的所有项意味着您需要散列该值,然后遍历表中非空项的“链”,以查找散列到相同值的项的数量。但对于散列到相同值的项数来说,这并不是线性的-- 它与散列到相同或冲突值的项数成线性关系

    Linear probing 是哈希表的另一种实现,其中不使用任何列表(链)进行冲突。相反,您只需在阵列中找到最近的可用点,从预期位置开始,然后向前。数组填充的越多,发现下一个位置也在使用的机会就越大,因此只需继续搜索即可。位置由使用 散列为相同或冲突值的项 ,尽管您永远不会(也不在乎)这两种情况是哪一种,除非您在那里明确看到现有元素的哈希。

    This CppCon presentation video 对哈希表进行了很好的介绍和深入分析。