[英]Hash : How does it work internally?
这听起来可能是一个非常模糊的问题,但事实并非如此。 我在维基上经历过Hash函数描述,但理解它并不是很有帮助。
我正在寻找像Hashing这样相当复杂的主题的简单答案。 这是我的问题:
HashMap
, HashTable
和HashList
什么HashList
? Hash
和LinkedList
被问到,是否有任何特定的逻辑来测试受访者的知识? 我知道我的问题清单很大但我真的很感激,如果我能够对这些问题得到一些明确的答案,我真的想了解这个主题。
这是关于散列的一个很好的解释。 例如,您希望存储字符串“Rachel”,您将哈希函数应用于该字符串以获取内存位置。 myHashFunction(key: "Rachel" value: "Rachel") --> 10
。 该函数可能会为输入“Rachel”返回10,因此假设您有一个大小为100的数组,则将“Rachel”存储在索引10处。如果要检索该元素,只需调用GetmyHashFunction("Rachel")
,它将返回10注意,对于此示例,键是“Rachel”,值是“Rachel”,但您可以使用该键的另一个值,例如出生日期或对象。 您的哈希函数可能会为两个不同的输入返回相同的内存位置,在这种情况下,如果您要实现自己的哈希表,则可能会发生冲突,您可能需要使用链表或其他技术来处理此问题。
以下是一些常用的哈希函数。 良好的散列函数满足:每个键同样可能散列到n个内存插槽中的任何一个,与任何其他键散列到的位置无关。 其中一种方法称为除法。 我们通过将k的余数除以n,将密钥k映射到n个时隙之一。 h(k) = k mod n
。 例如,如果您的数组大小为n = 100
且您的密钥是整数k = 15
那么h(k) = 10
。
Hashtable是同步的,Hashmap不是。 Hashmap允许将空值作为键,但Hashtable不允许。
哈希表的目的是在添加和获取元素时具有O(c)恒定的时间复杂度。 在大小为N的链表中,如果要获取最后一个元素,则必须遍历所有列表,直到获得它为止,因此复杂度为O(N)。 使用哈希表如果要检索元素,只需传递密钥,哈希函数将返回所需的元素。 如果哈希函数很好地实现,它将处于恒定时间O(c)这意味着你不必遍历存储在哈希表中的所有元素。 您将立即获得该元素。
程序员/开发人员计算机科学家需要了解数据结构和复杂性=)
Integer
, String
等)使用不同的算法来计算哈希码。 Hashing正在将给定实体(在java术语中 - 一个对象)转换为某个数字(或序列)。 哈希函数是不可逆的 - 即您无法从哈希中获取原始对象。 在内部实现它(对于java.lang.Object
,通过JVM获取一些内存地址)。
JVM地址是不重要的细节。 每个类都可以使用自己的算法覆盖hashCode()
方法。 Modren Java IDE允许生成好的hashCode方法。
Hashtable和hashmap是一回事。 它们是键值对,其中键是经过哈希处理的。 散列列表和散列集不存储值 - 仅存储键。
常量时间意味着无论哈希表(或任何其他集合)中有多少条目,通过其键查找给定对象所需的操作数是不变的。 那是-1,或接近1
这是基本的计算机科学材料,并且假设每个人都熟悉它。 我认为谷歌已经指定哈希表是计算机科学中最重要的数据结构。
我将尝试简单解释散列及其用途。
首先,考虑一个简单的清单。 此类列表上的每个操作(插入,查找,删除)都具有O(n)复杂性,这意味着您必须解析整个列表(或平均一半)才能执行此类操作。
散列是一种非常简单有效的加速方法:考虑我们将整个列表分成一组小列表。 一个这样的小列表中的项目将有一些共同点,这个东西可以从密钥中推断出来。 例如,通过列出名称,我们可以使用第一个字母作为质量,选择要在哪个小列表中查找。 通过这种方式,通过按键的第一个字母对数据进行分区,我们获得了一个简单的哈希,它可以将整个列表拆分成~30个较小的列表,这样每个操作都需要O(n)/ 30次。
但是,我们可以注意到结果并不完美。 首先,它们只有30个,我们无法改变它。 其次,有些字母的使用频率高于其他字母,因此带有Y
或Z
的集合将远小于带有A
的集合。 为了获得更好的结果,最好找到一种方法来分割大小相同的项目。 我们怎么能解决这个问题? 这是您使用哈希函数的地方。 这是一个能够创建任意数量的分区的功能,每个分区的项目数大致相同。 在我们的名字示例中,我们可以使用类似的东西
int hash(const char* str){
int rez = 0;
for (int i = 0; i < strlen(str); i++)
rez = rez * 37 + str[i];
return rez % NUMBER_OF_PARTITIONS;
};
这将确保非常均匀的分布和可配置数量的集合(也称为桶)。
Hashing是什么意思,它在内部如何运作?
散列是字符串较短的固定长度值或表示原始字符串的键的转换。 它没有索引。 哈希的核心是哈希表。 它包含一系列项目。 散列表包含数据项密钥的索引,并使用此索引将数据放入数组中。
它遵循什么算法?
简单来说,大多数哈希算法都使用逻辑“index = f(key,arrayLength)”
最后,为什么在大多数面试问题Hash和LinkedList被问到,是否有任何特定的逻辑来测试受访者的知识?
它是关于你在逻辑推理上有多好。 这是每个程序员都知道的最重要的数据结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.