C# 任何活动对象的哈希函数(哈希表)?
不确定重新打开我以前的散列线程是否明智。 尽管如此,我还是很想知道这是如何秘密进行的 假设:我们有一个包含n(其中n<无穷大)元素的哈希表,其中渐近时间复杂度为o(1);我们(CLR)通过应用一些散列函数(Hn-1散列函数,其中n>1)实现了这一点 问:有人能解释一下,当我们查找(检索)任何元素时(如果使用不同的哈希函数),CLR是如何将键映射到哈希代码的吗?CLR如何跟踪(如果是)任何活动对象(哈希表)的哈希函数C# 任何活动对象的哈希函数(哈希表)?,c#,c#-4.0,hash,c#-3.0,hashmap,C#,C# 4.0,Hash,C# 3.0,Hashmap,不确定重新打开我以前的散列线程是否明智。 尽管如此,我还是很想知道这是如何秘密进行的 假设:我们有一个包含n(其中n1)实现了这一点 问:有人能解释一下,当我们查找(检索)任何元素时(如果使用不同的哈希函数),CLR是如何将键映射到哈希代码的吗?CLR如何跟踪(如果是)任何活动对象(哈希表)的哈希函数 提前谢谢。不确定我是否理解您的问题,但是.NET中的每个对象都实现了GetHashCode函数,该函数返回一个在字典/哈希表中可用(并使用)的哈希代码,因此对象本身负责生成一个好的哈希代码 当然,
提前谢谢。不确定我是否理解您的问题,但是.NET中的每个对象都实现了
GetHashCode
函数,该函数返回一个在字典/哈希表中可用(并使用)的哈希代码,因此对象本身负责生成一个好的哈希代码
当然,由于哈希代码是int,因此可能(也将)存在冲突。冲突由字典/哈希表处理/解决。哈希代码不能唯一标识对象。它只是用来快速将物体放入桶中。一个铲斗中的元件可以但不必相等,但不同铲斗中的元件必须不相等 从概念上讲,您可以将引用类型上的默认
GetHashCode()
实现想象为在每个实例中使用一个字段,该字段包含在对象创建时初始化的hashcode的随机值。实际的实现有点复杂,但这在这里并不重要
由于只有20亿个不同的哈希代码,如果元素多于此值,大多数哈希表实现的O(1)
运行时将崩溃。当然,分布必须是好的,也就是说,不能有太多的散列冲突,但有一些并不是大问题
对于具有值语义的类型,您可以一致地重写
Equals
和GetHashCode
以使用确定相等性的字段。每个对象都实现GetHashCode()
函数和Equals()
函数。
这些的默认实现与对象引用相关。例如a.Equals(b)
将返回与object.ReferenceEquals(a,b)
相同的值。这意味着如果两个对象引用相等,那么它们的哈希代码也相等
在某些情况下,您需要为Equals()
函数提供不同的语义。在这些情况下,您必须维护合同,如果a.Equals(b)
,则a.GetHashCode()==b.GetHashCode()
使用的散列函数很多,每个函数都有自己的优缺点。有一个有用的解释。实际使用的函数不是您应该担心的,在哈希表中保持平均值的最重要的是(理想情况下)确保将插入的对象的
GetHashCode()
结果尽可能接近均匀分布 从概念上讲,有两个哈希函数。您可能已经猜到,第一个散列函数是键对象的GetHashCode
方法。第二个散列函数是第一个散列函数返回的密钥的散列
因此,假设一个哈希表有1024个项目的容量,您将插入两个键:K1
和K2
K1.GetHashCode()
返回1023K2.GetHashCode()
返回65535
然后,代码将返回的键除以哈希表大小,并取余数。因此,这两个键都映射到哈希表中的位置1023
K1
已添加到表中。当需要添加K2
时,会发生冲突。因此,代码求助于第二个哈希函数。第二个散列函数可能是某种类型的“位混合器”(通常是计算散列码的最后一个阶段),用于随机化返回键中的位。从概念上讲,代码如下所示:
int hashCode = K2.GetHashCode();
int slot = hashCode % 1024;
if (table[slot] != null)
{
int secondHashCode = BitMixer(hashCode);
slot = secondHashCode % 1024;
}
这里的要点是,代码不必跟踪不同密钥的多个哈希函数。它知道它可以调用
Key.GetHashCode()
来获取对象的哈希代码。从那里,它可以调用自己的一个或多个位混合器函数来生成额外的哈希代码。感谢您澄清您的哈希表包含的元素少于无穷多!;)但是,与其说这是一个完全无用的评论,我建议先阅读HashTable类上这个MSDN页面上的注释:好吧,这和上一个问题是同一个问题,不是吗?我感兴趣的是:你在哪里读到的?我不能说我深陷其中,但我一直认为objects GetHashCode方法正好提供了这样一个值。这与您的链接问题有什么不同?可能重复@Kiley Naro:小于无穷大只意味着任意数量的元素。在MSDN(你们所指的url)中并没有关于冲突的信息。第一个线程详细解释这个问题。请看一看,如果需要进一步澄清,请让我知道。你根本不了解我的问题。无论如何,谢谢你的努力。然后也许你可以澄清你的问题。您想知道字典如何使用哈希代码吗?