【发布时间】:2016-05-29 14:40:12
【问题描述】:
我目前正在从“算法介绍 3”中学习哈希表。尝试从统计角度理解开放寻址时会感到非常困惑。假设m是哈希表长度,线性探测和二次探测只能产生m个可能的探测序列。但是,按照开放寻址的定义,可能的键值个数大于散列值的个数,即负载因子n/m
问:实际上,如果负载因子小于 1,我们为什么还要打扰开放寻址?为什么不将每个键投影到一个整数并将它们排列在一个数组中?
【问题讨论】:
标签: language-agnostic hashtable
我目前正在从“算法介绍 3”中学习哈希表。尝试从统计角度理解开放寻址时会感到非常困惑。假设m是哈希表长度,线性探测和二次探测只能产生m个可能的探测序列。但是,按照开放寻址的定义,可能的键值个数大于散列值的个数,即负载因子n/m
问:实际上,如果负载因子小于 1,我们为什么还要打扰开放寻址?为什么不将每个键投影到一个整数并将它们排列在一个数组中?
【问题讨论】:
标签: language-agnostic hashtable
问:实际上,如果负载因子小于 1,我们为什么还要打扰开放寻址?为什么不将每个键投影到一个整数并将它们排列在一个数组中?
因为在许多使用哈希表的情况下,没有好的 O(1) 方法可以“将每个键投影到 [不同的、非荒谬的] 整数”数组索引。
一个简单的思想实验说明了这一点:假设您希望用户键入四个三个大写字母的键,并且您希望将它们存储在维度为 10 的数组中的某个位置。您有 264可能的输入,因此无论您的逻辑是什么,平均有 264/10 个将“投影...到一个整数” 表示相同的数组位置。当您意识到 "project[ion]" 无法避免潜在的"collisions",并且该投影在逻辑上与 "hashing" 操作相同时 em> 并修改为 “bucket”,然后将需要一些冲突处理逻辑,您提出的“替代”变回哈希表....
线性探测和二次探测只能产生m个可能的探测序列,假设m是哈希表长度。但是,按照开放寻址中的定义,可能的键值数量大于哈希值的数量,即负载因子 n/m
它们是非常令人困惑的陈述。 “散列值的数量”不受任意限制——您可以使用 32 位散列生成约 40 亿散列值中的任何一个、512 位散列或您喜欢的任何其他大小。鉴于您的语句的结构是“a > b,即负载因子 n/m n”,您暗示“a " 和 "m" 和 "b" 和 "n" 是同一个东西:
您指的是m - “负载因子 n/m” 要求是哈希表中的桶数 - 作为 “可能的键值number":不是,这意味着什么?
您指的是n - “负载因子 n/m” 需要存储在哈希表中的键的数量 - 作为 “的数量散列值”:不是,除非是在对键进行散列时生成那么多(不一定是不同的)散列值的琐碎意义
实际上,如果预定义hash函数,则只有n个可能的探测序列,小于m。
同样,这是一个定义非常不明确的陈述。 n 键的散列最多可以识别 n 不同的桶,碰撞处理将从这些桶开始,但那些 n 可以在 m 桶内的任何地方开始,因为散列函数的工作是喷射他们周围。而且,那又怎样?
同样的事情也适用于双重哈希。如果书上说,从一组通用散列函数中随机选择一个散列函数,那我可以理解。
了解什么?
在开放寻址分析中没有引入随机性,就使得基于通用哈希的性能分析变得模糊。
当然。散列的“可重复随机性”是一个非常方便且切实的基准,可以用来比较具体的实现。
我从来没有在实践中使用过哈希表,也许我过于关注细节了。但是我对哈希表的实际使用也有这样的疑问:
【讨论】: