问题描述
我正在学习HashSet-s,但我不太了解它们如何构建表。我读过的每一篇文章都谈论%哈希集函数,这似乎意味着我应该向HasSet中添加几个小数字(int)(例如1、7、14),然后添加一个大数字(例如2732780)-该表用于HashSet将立即增长为无数单元格的巨大规模。我对么?如果不是,那么数字/元素以什么形式存储?在哪里可以详细了解?
更新:所以要澄清一下:
说我的哈希函数是x =(input / 10),y =(input%10),这意味着在上面的示例中,当您添加1、7和14时,HashSet会像这样构建表:
问题是,如果添加2732780,会发生什么?桌子应该爆炸了吧?还有大量的空数字吗?
解决方法
哈希集使用一个哈希函数。这会将任何数据类型转换为int。然后将此int放入存储桶中。这是通过将%
与可用存储区的数量一起使用来完成的。
说它是x % 10
。然后看起来像这样:
|input |hashcode |bucket
|1 | 1 |1
|7 | 7 |7
|14 | 14 |4
|2732780 | 2732780 |0
如果有两个条目具有相同的存储桶,则将保留一个列表,并且该存储桶中的查找是线性的。该实施将根据需要增加存储桶。
,在Java中,HashSet是使用HashMap实现的(从算法的角度来看,在C#中没有理由不应该这样做)。
本文介绍了HashMap如何很好地工作: https://www.geeksforgeeks.org/internal-working-of-hashmap-java/
关键是要有地图容量的概念。这是保存地图存储区的数组。选择哪个索引的计算是:
index = hashCode(key)&(n-1)
,n为容量。这意味着,当您在set / map中插入更多条目时,实现将不断增长并重新哈希其条目。