达到最大链长时调整哈希表的大小

时间:2017-01-22 23:05:30

标签: java algorithm hashtable

我正在为教育目的实现哈希表。散列表用数组实现,碰撞用链表处理。说明书说我可以插入相同的项目,而无需检查以提高插入速度。但是当链长达到最大允许值时,需要调整哈希表的大小。但是我发现调整大小根本没有帮助,因为相同的项目仍然会进入相同的存储桶甚至数组长度增加。我在这里错过了什么吗?非常感谢你。

3 个答案:

答案 0 :(得分:2)

我们举一个例子:三个对象,包含哈希码7,23和47。

如果散列表的大小为8,那么通过模运算,所有这些对象都将进入散列桶7。

另一方面,如果哈希表的大小为16,那么前两个将进入哈希桶7,而另一个将进入桶15。

答案 1 :(得分:2)

  

说明书说我可以插入相同的项目,而无需检查以提高插入速度。

你不能完全跳过检查,因为你最终会在同一条链上重复。

  

但是我发现调整大小根本不会有所帮助,因为相同的项目仍会进入相同的存储桶,即使数组长度增加也是如此。

仅对表大小以下的哈希值发生这种情况。对于大于表大小的值,%运算符通常会将项放在不同的存储桶中,假设您避免了别名问题。

为避免混叠,请使用与素数对应的表格大小。有关此问题的详细信息,请参阅this Q&A

答案 2 :(得分:0)

我可以告诉jdk如何处理它。您的条目(键)覆盖哈希码 - 这是一个int(由32位组成)。当你有16个桶(内部数组的长度为16)时,内部执行的操作是为了找出条目的去向:

 hash_code & (array.lenght - 1) // this is the same as modulo operation
                                // if array.lenght is power of two.

这意味着当您将一个条目放入映射时,只会考虑条目的哈希码的最后4位。

现在当你填写那16个条目(你实现一个加载因子)时:内部数组变得更大(让它加倍),所以它现在有32个条目。

这意味着计算条目的去向将被计算出来:

   hash_code & (32 - 1) // now there are 5 bits take into consideration

现在所有条目都被重新哈希(因为现在还有一个位),您的条目可能会在不同的桶中结束。