让我们以线性探测为例,因为它很简单。
你有一个(虚构的)哈希表,他们的键是这样的:
1 2 3 4 5 6 7
[23| | 44|67|89| |22]
您要检查不存在的密钥99。它给出哈希值5。
当然算法是这样的:
Check 5: X
Check 6: X
Check 7: X
Check 1: X
Check 2: X
Check 3: X
Check 4: X
Reached 5 again: Key not found
当然,除非检查整个表,否则算法无法判断密钥是否存在。
然而,在搜索答案时,我偶然发现了这个页面:https://msdn.microsoft.com/en-us/library/system.collections.hashtable.containskey(v=vs.110).aspx表明它是O(1)。当然,如果密钥存在,它可以是O(1),但它不会平均不会吗?最坏的情况(每次关键不存在?)都是O(n)。
我认为这是正确的吗?
编辑: 我刚刚意识到当它撞到一个空的空间时它会停止......所以这意味着如果表满了就会达到O(n)?哪个必须是你不想要群集的原因?
答案 0 :(得分:1)
我刚刚意识到当它撞到空旷的空间时会停止......所以 这意味着如果桌子已满,它只会达到O(n)?哪一个 必须是你不想要群集的原因吗?
你是对的。请记住,使用开放寻址作为冲突解决技术(线性探测属于开放寻址)的每个体面的哈希表实现都存储一个称为加载因子的特殊数字。加载因子是哈希表中项目数与可用时隙总数之间的比率。当负载因子增加超过某个值时,哈希表会扩展 - 这是保持探测数量足够小并确保良好性能的方法。
由于您搜索了C#实现,我花时间在C#2.0中找到了一个描述哈希表实现的documentation。它声明:
如上所述,Microsoft已将Hashtable调整为使用默认值 载荷系数为0.72。因此,平均3.5你可以期待 每次碰撞探测。因为这个估计不会因此而变化 Hashtable中的项目数,a的渐近访问时间 Hashtable是O(1),它比O(n)搜索时间更好 对于阵列。