微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在哈希表的哈希函数中模数不够?

如何解决为什么在哈希表的哈希函数中模数不够?

我经常看到或听说模数被用作散列的最后一步或散列之后。例如h(input)%N 其中 h 是散列函数% 是模运算符。如果我正在设计一个哈希表,并且想要将一大组键映射到哈希表的较小索引空间,那么模运算符不能实现吗?此外,如果我想随机化散列表中这些位置的分布,模数生成的余数是否不够?散列函数 h 在模运算符之上提供了什么?

解决方法

我经常看到或听说模数被用作散列的最后一步或散列之后。例如h( input ) % N 其中 h 是散列函数,% 是模运算符。

确实如此。

如果我正在设计一个哈希表,并且想将大量键映射到哈希表的较小索引空间,模数运算符不能实现吗?

这正是模运算符的目的:限制数组索引的范围,所以

但是您不能简单地单独使用模运算符:模运算符需要一个整数值:您无法获得“N 上的字符串的模”或“{{1} 上的对象图的模” }}"[1].

此外,如果我想随机化散列表中这些位置的分布,模数生成的余数是否不够?

不,它没有 - 因为模运算符不会给你伪随机输出 - 也没有任何类型的雪崩效应 - 这意味着相似的输入值将具有相似的输出哈希,这将导致散列表箱中聚类,由于散列冲突的可能性大大增加,这将导致性能不佳(因此需要较慢的技术,例如线性探测,这会破坏散列表的目的因为您失去了 N 次查找时间。

散列函数 O(1) 在模运算符之上提供了什么?

h可以是任何东西,尤其是非整数值。


[1] 从技术上讲,如果您使用对象的内存地址的值(即对象指针),这是可能的,但如果您有不使用 的哈希表键,则这不起作用对象标识,例如堆栈分配的对象或自定义 h

,

首先,散列函数的主要目的是将不是数字的东西变成数字。即使您只是在此之后使用模数来获取您范围内的数字,获取数字仍然是第一步,并且是哈希函数的责任。如果您正在对整数进行散列并且您只是将这些整数用作它们自己的散列,那么并不是没有散列函数,而是您选择了恒等函数作为您的散列函数。如果你不写出函数,那意味着你内联了它。

其次,哈希函数可以提供更不可预测的分布,以减少无意冲突的可能性。人们使用的数据通常包含模式,如果您只是使用带模数的简单恒等函数,则输入中的模式可能是模数更可能导致冲突。散列函数提供了一个机会来分解它,因此模数不太可能暴露原始数据序列中的模式。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。