Java 散列集如何引起冲突?

Java 散列集如何引起冲突?,java,hashset,Java,Hashset,如果一个散列集只包含任何不同元素的一个实例,那么在这种情况下如何发生冲突 既然给定的元素只有一个,那么负载系数怎么会成为问题呢 虽然这是家庭作业,但不是给我的。我正在辅导某人,我需要知道如何向他们解释。散列表(散列集是各种各样的)背后的一般思想是,您有许多包含“键”值的对象(例如字符串),您希望将它们放入某种容器中,然后能够通过它们的“键”找到单个对象值,而无需检查容器中的每个项目 例如,可以将值放入排序数组中,然后进行二进制搜索以查找值,但是如果有大量更新,则维护排序数组的成本很高 所以键值是

如果一个散列集只包含任何不同元素的一个实例,那么在这种情况下如何发生冲突

既然给定的元素只有一个,那么负载系数怎么会成为问题呢

虽然这是家庭作业,但不是给我的。我正在辅导某人,我需要知道如何向他们解释。

散列表(散列集是各种各样的)背后的一般思想是,您有许多包含“键”值的对象(例如字符串),您希望将它们放入某种容器中,然后能够通过它们的“键”找到单个对象值,而无需检查容器中的每个项目

例如,可以将值放入排序数组中,然后进行二进制搜索以查找值,但是如果有大量更新,则维护排序数组的成本很高

所以键值是“散列”的。例如,可以将所有字符的ASCII值相加,以创建一个数字,即字符串的“哈希”。(有更好的散列计算算法,但精确的算法并不重要,这是一个很容易解释的算法。)

当你这样做的时候,你会得到一个数字,对于一个十个字符的字符串,它的范围可能在600到1280之间。现在,如果你除以,比如说,500,然后取余数,你将得到一个介于0和499之间的值。(请注意,字符串不必是10个字符——更长的字符串将添加到更大的值,但当您除法并获取余数时,仍然会得到一个介于0和499之间的数字。)

现在创建一个包含500个条目的数组,每次获得一个新对象时,按照上面所述计算其哈希值,并使用该值索引到数组中。将新对象放入与该索引对应的数组项中

但是(特别是使用上面的朴素散列算法),您可以使用相同的散列拥有两个不同的字符串。例如,“ABC”和“CBA”将具有相同的散列,并且最终将进入数组中的相同插槽

要处理这种“冲突”,有几种策略,但最常见的是在数组项之外创建一个链表,并将各种“哈希同义词”放入该列表中

您通常会尝试让数组足够大(并且有更好的散列计算算法)以最小化此类冲突,但是,使用散列方案无法绝对防止冲突


请注意,同义词列表中的多个条目并不相同——它们具有不同的键值——但它们具有相同的哈希值。

假设您有一组整数,并且您的哈希函数是mod 4。如果您尝试插入整数0、4、8、12、16等,它们将全部合并。(mod 4是一个糟糕的散列函数,但它说明了这个概念)

假设一个适当的函数,载荷系数与发生碰撞的可能性相关;请注意,我说的是相关和不相等,因为这取决于处理碰撞时使用的策略。通常,高负载系数会增加碰撞的可能性。假设您有4个插槽,并且使用mod 4作为哈希函数,当加载因子为0(空表)时,不会发生冲突。当您有一个元素时,发生冲突的概率为.25,这显然会降低性能,因为您必须解决冲突

现在,假设您使用线性探测(即,在发生碰撞时,使用下一个可用条目),一旦达到表中的3个条目,则发生碰撞的概率为.75,如果发生碰撞,在最好的情况下,您将进入下一个条目,但在最坏的情况下,您将必须通过3个条目,因此,冲突意味着,与直接访问不同,您平均需要一个线性搜索,平均包含2个项目

当然,您有更好的策略来处理碰撞,通常,在非病理性情况下,0.7的负载是可以接受的,但在碰撞之后,碰撞会激增,性能会下降