Quadratic Probing : 在现实生活中的哪种情况下,它的复杂度为 O(n)

问题描述

我正在学习数据结构和算法。我被教导几乎每个 hashmap 操作都几乎是 O(1)。这是一种执行二次探测分辨率的方法,它返回所需对象的位置。

private int findPos( Object x )
{
    int offset = 1;
    int currentPos = myhash( x ); //Using quadratic probing 
    
    while( array[ currentPos ] != null &&
            !array[ currentPos ].element.equals( x ) )
    {
        currentPos += offset;  // Compute ith probe
        offset += 2;
        if( currentPos >= array.length )
            currentPos -= array.length;
    }
    
    return currentPos;
}

我正在做作业,我不得不在作业中找出这种方法的复杂性。这是场景:

该数组表示一个英语词典,其中每个元素都是其中的一个单词。这个作业的答案是 O(1) 复杂度。但我想知道为什么不是 O(n) 复杂度,因为里面有很多元素(大约 171,476 个单词)会导致很多冲突。换句话说,我怎么能确定,从这个场景来看,这个方法总是 O(1) ?

编辑 我的家庭作业的问题是:在最坏情况情况下,这种方法的复杂性如何。还是 O(1) 吗?

解决方法

非最坏情况.... 它是 O(1) 而不是 O(n) 因为搜索时间不取决于数组的大小。是的,您会遇到更多元素的更多冲突,但平均而言每次搜索不会有更多冲突,因为数组的大小随着 n 的增加而增加。

编辑:由于问题规定数据是来自英语的单词,因此 n 的最大可能大小有限制,这意味着您实际上可以保证您的哈希函数没有冲突,这将使答案 O(1)即使在最坏的情况下。

,

这种方法在最坏情况下的复杂度是多少。即使在最坏的情况下,它仍然是 O(1) 吗?

要回答您的问题,您确实必须定义最坏情况的含义。哈希表的实现非常依赖于两个因素:您打算存储在哈希表中的数据的(概率)分布,以及您定义的哈希函数。了解这两个因素后,您就可以进行平均案例分析。没有这两条信息,你可以假设最坏的情况,例如:

  • 您将始终获得相同的值来存储数字“1”
  • 你的哈希函数是 f(x) = x

在这种情况下,如果您对存储桶使用链表,那么最坏的情况确实是 O(n)。

但是,如果您有更多信息,例如您的数据遵循均匀分布并且您使用合理的散列函数,则您可以在平均情况下显示大多数操作应该是 O(1) .在上一句中,描述符“平均”是通过对数据遵循的概率分布求平均值来精确定义的。


我不清楚您需要多详细的分析,但通常使用开放寻址(与哪个无关),平均运行时间的分析如下。

a = n / N 为哈希表的负载因子,其中 n 是存储的元素数量,N 是存储桶的数量。假设没有聚类问题(由于数据或散列函数)并且所有探测的可能性相等(证明二次探测是正确的证据是分开的),那么你可以断言

P(probe hits occupied bucket) = a
P(probe hits unoccupied bucket) = 1-a
P(probe hits unoccupied bucket in 2 steps) = a (1-a)
P(probe hits unoccupied bucket in k steps) = a^{k-1} (1-a)

因此探测的平均运行时间为

E(number of steps in probe) = \sum {for k = 0 to m} k a^{k-1}(1-a)
                            <=\sum {for k = 0 to infty} k a^{k-1}(1-a)
                            = (1-a) / (1-a)^2
                            = 1 / (1 - a)

其中无限和由 arithmetico-geometric series 给出,m 是探测步骤数的上限(取决于探测技术,通常需要单独证明探测技术终止在有限的步骤中m。)

如果我们保持合理的负载因子 a,比如说 a = n / N = .5,那么

E(number of steps in probe) <= 1 / (1-.5) = 2

因此 E(number of steps in probe) 是 O(1)。

整个分析的关键在于能够认识到无限和有一个很好的收敛形式。

总结一下,我上面给出的证明适用于一般情况,但要求您使用的探测技术满足以下条件(可能需要单独证明):

  • 探测技术基于命中未占用/已占用存储桶(即 P(probe hits occuppied bucket) = a)的负载因子产生统一概率
  • 探测技术在有限数量的步骤中终止

根据您的分析必须有多详细,您可能需要证明二次探测的这两个属性才能完成证明。 (请注意,只有当负载因子为