我使用数组作为散列算法的散列表,其值为:
int[] arr={4 , 5 , 64 ,432 };
和数组中连续整数的键为:
int keys[]={ 1 , 2 , 3 ,4};
有人可以告诉我,将那些整数键与那些数组位置映射的好方法是什么?以下是一种简短且更好的方法,几乎没有碰撞(或更大的值)?
keys[i] % arrlength // where i is for different element of an array
提前致谢。
答案 0 :(得分:2)
我假设您正在尝试将某种哈希表实现为练习。否则,您应该只使用java.util.HashMap或java.util.HashTree或类似的。
对于一小部分值,如上所述,您的解决方案很好。当你的数据变得更大时,真正的问题就出现了。
您已经发现碰撞是不受欢迎的 - 这是事实。有时,对可能的键的一些了解可以帮助您设计一个好的哈希函数。有时,您可以假设密钥类具有良好的hash()
方法。由于hash()是Object定义的方法,因此每个类都实现它。能够利用密钥的hash()方法,而不是专门为您的地图构建新算法,这是最好的。
如果所有整数键都具有相同的可能性,那么mod函数会将它们均匀地分布在不同的桶中,从而最大限度地减少冲突。但是,如果您知道密钥将连续编号,那么使用List而不是HashMap可能会更好 - 这将保证不会发生冲突。
答案 1 :(得分:1)
任何不使用内置HashMap的原因?你必须使用Integer,而不是int。
java.util.Map myMap = new java.util.HashMap<Integer, Integer>();
由于您想要实现自己的,然后通过阅读Wikipedia article首先刷新哈希表。之后,您可以学习HashMap source code。
This StackOverflow question包含用于实现快速哈希映射的有趣链接(对于C ++而言),this one(对于Java)也是如此。
答案 2 :(得分:1)
给自己写一本关于算法和数据结构的书,并阅读关于哈希表的章节(Wikipedia article也是一个很好的切入点)。这是一个复杂的主题,远远超出了像这样的Q&amp; A网站的范围。
对于初学者来说,使用数组大小的模数通常是可怕的哈希函数,因为当值是数组大小的倍数或其除数之一时,它会导致大量冲突。这有多糟糕取决于数组大小:它具有的除数越多,碰撞的可能性就越大;当它是素数时,它不是太糟糕(但也不是很好)。