Language agnostic 开放寻址分析

Language agnostic 开放寻址分析,language-agnostic,hashtable,Language Agnostic,Hashtable,我目前正在学习“第三代算法简介”中的哈希表。当试图从统计学的角度理解开放寻址时,会感到非常困惑。假设m是哈希表长度,则线性探测和二次探测只能生成m个可能的探测序列。然而,如开放寻址中所定义的,可能的键值数大于散列值数,即加载因子n/m

我目前正在学习“第三代算法简介”中的哈希表。当试图从统计学的角度理解开放寻址时,会感到非常困惑。假设m是哈希表长度,则线性探测和二次探测只能生成m个可能的探测序列。然而,如开放寻址中所定义的,可能的键值数大于散列值数,即加载因子n/m<1。实际上,如果预先定义了哈希函数,则只存在n个可能的探测序列,这小于m。同样的事情也适用于双重散列。如果书中说,一个散列函数是从一组通用散列函数中随机选择的,那么,我可以理解。由于在开放寻址分析中没有引入随机性,因此基于通用散列的性能分析变得模糊。我从来没有在实践中使用过哈希表,也许我对细节做得太多了。但我对哈希表的实际用途也有这样的疑问:

问:事实上,如果负载因子小于1,我们为什么还要麻烦开放寻址呢?为什么不将每个键投影到一个整数,并将它们排列在一个数组中

问:事实上,如果负载因子小于1,我们为什么还要麻烦开放寻址呢?为什么不将每个键投影到一个整数,并将它们排列在一个数组中

因为在许多使用哈希表的情况下,没有好的O(1)方法“将每个键投影到一个[distinct,not荒诞地稀疏的]整数”数组索引

一个简单的思维实验说明了这一点:假设您希望用户键入四个三个大写字母键,并希望将它们存储在一个维度为10的数组中的某个位置。您有264个可能的输入,因此无论您的逻辑是什么,平均而言,其中264/10将“投影到一个整数”,指示相同的数组位置。当您意识到“project[ion]”无法避免潜在的“冲突”,并且投影在逻辑上与“hash”和“bucket”是相同的操作,那么将需要一些冲突处理逻辑,您提出的“备选方案”将变回哈希表

假设m是哈希表长度,则线性探测和二次探测只能生成m个可能的探测序列。然而,如开放寻址中所定义的,可能的键值数大于散列值数,即加载因子n/m<1

它们是非常令人困惑的陈述。“散列值的数量”不是任意限制的-您可以使用32位散列生成约40亿个散列值中的任何一个,512位散列,或任何其他您喜欢的大小。鉴于您的陈述结构为“a>b,即荷载系数n/m<1”,且“n/m<1”可改写为“nn”,您暗示“a”和“m”与“b”和“n”是同一事物:

  • 您指的是
    m
    “加载因子n/m”要求是哈希表中的存储桶数,即“可能的键值数”:它不是,这意味着什么

  • 您指的是
    n
    “加载因子n/m”要求是存储在哈希表中的键的数量,即“哈希值的数量”:它不是,除非在对键进行哈希运算时生成许多(不一定是不同的)哈希值

实际上,如果预先定义了哈希函数,则只存在n个可能的探测序列,这小于m

同样,这是一个定义很差的声明。对
n
键进行散列最多可以识别
n
个不同的桶,冲突处理将从这些桶开始,但是这些
n
几乎可以从
m
桶中的任何地方开始,因为散列函数的任务是将它们四处喷洒。那又怎样

同样的事情也适用于双重散列。如果书中说,一个散列函数是从一组通用散列函数中随机选择的,那么,我可以理解

明白什么

由于在开放寻址分析中没有引入随机性,因此基于通用散列的性能分析变得模糊

当然。散列的“可重复随机性”是一个非常方便和有形的基准,可以与特定的实现进行比较

我从来没有在实践中使用过哈希表,也许我对细节做得太多了。但我对哈希表的实际用途也有这样的疑问: