我开始学习CLRS的散列(Cormen等人)。我能够理解数学过程以及计算机实现如何遵循。该书简单地将数学程序陈述为 -
-> multiply the key k with a constant A (0<A<1), results into kA;
-> extract the fractional part of kA by doing (kA mod 1);
-> multiply the result with m (usually taken to be a power of 2 for easy
implementation on computers);
-> take the floor of this result and that is the hashed value;
-> therefore, this is the hashing function, h(k) = floor[m*(kA mod 1)]
该书进一步阐述了如何在大多数计算机上实现它,它优于分割方法和Knuth对“A”值的建议。
我无法理解的是,为什么我们遵循这个过程,特别是将键与数字(A)在0到1的范围内相乘,然后取小数部分,然后乘以m,然后再发言?
这是否会产生“非常类似”SUHA的散列值(假设简单的均匀散列),即理想情况下每个键应独立地散列到m个槽中的任何一个,所以这种方法会产生“更接近”这个理想的结果吗?
理想情况下,散列应满足简单均匀散列的假设。
例如在散列函数h(k): U--> {0...m-1}
中U
是可能键的宇宙,m
是表的大小
这意味着密钥Universe中的任何密钥应该同样可能在每次散列时都在同一位置,并且密钥的分布均匀地分布在所有位置上吗?
嗯,在实践中并不容易,我们不知道提前分配密钥的可能性,即使我们做了,我们仍然不知道哪些将被从那个宇宙中抽出。
因此,我们需要根据我们对密钥的了解来实现,这些密钥可以在k
上创建一些表现良好的计算并在表中很好地分配密钥。
这就是我们在方法之间进行交易的地方,
采用除法方法:只需h(k) = k mod m
Key模数表的大小。简单,快速,只产生合法的价值,但你必须非常谨慎地选择你的m
!例如,如果表的幂是2的幂,那么基本上是k
and的最低有效位,这些键可能显示某种结构。所以选择m
的素数可能接近2的精确幂。
让我们继续使用乘法方法进行一些对比:h(k) = floor[m*(kA mod 1)]
,其中(0<A<1)
我们将我们的密钥乘以一个小数,因此mod 1
可以将小数分量取出。基本上你会用m
乘以0到0但不包括1之间的数字,最后,我们取得结果的底线得到一个整数。这比分割方法慢但是你选择什么m
并不重要m
的价值并不重要!
回到你的问题,它完全取决于你有什么样的实现,因此你应该如何相应地使用哈希表。那里有很多。