代码改变世界

从顺序查找窥探平均时间复杂度分析的一般化方法

2015-05-18 19:10  星星之火✨🔥  阅读(3373)  评论(1编辑  收藏  举报

顺序查找是在n 个元素的列表中查找一个给定项(或者说查找键)的一个简单的算法。它会检查列表中的连续元素,直到发现了匹配查找键的元素或者到达了列表的终点。

我们假设对输入规模为n 的数据做若干次查找,为了分析该算法的平均时间复杂度,还需要对规模为n 的输入做一些假设。

标准的假设是:

  • 成功查找的概率是P(0 ≤ P ≤ 1)
  • 对于任意的正整数i(1 ≤ i ≤ n),第一次匹配发生在列表第i 个位置的概率是相同的

基于这种假设,容易得出,在成功查找的情况下,对于任意的i,第一次匹配发生在列表的第i 个位置的可能性是p/n,并且在这种情况下该算法所做的比较次数显然是i。而在不成功查找的情况下,比较的次数是n,发生的概率是1-P。

因此,键值比较的平均次数:

Cavg(n) = 1·P(比较次数为1) + 2·P(比较次数为2) + 3·P(比较次数为3) + ... + n·P(比较次数为n) + n·P(查找失败)

      = 1·P/n + 2·P/n + ... + n·P/n + n(1-P)

    = P(n+1)/2 + n(1-P)

我们可以用一些简单的例子来验证这个一般性方程的正确性,例如,如果 P = 1(查找一定会成功的情况),顺序查找所做的键值比较的平均次数是(n+1)/2,这意味着,平均来说,该算法大约要检查表中一半的元素。如果P = 0(查找一定不成功的情况下),键值比较的平均次数将是n,因为这种情况下,算法会对列表中的n 个元素全部检查一遍。

从这个简单的例子中可以发现,平均效率的研究比起最差效率研究(对于本例Cworst(n) = n)和最优效率研究(对于本例Cbest(n)  = 1,同Cworst一样,它们几乎都是显然的)要困难的多。因为我们需要得到或者假设各类输入的概率分布(虽然这种假设看起来很合理,但是其正确性往往很难验证),来推导出我们希望得到的基本操作的平均次数。

然而真的有必要研究算法的平均效率吗?答案是很有必要。因为有很多重要的算法的平均效率比它们过于悲观的最差效率要好得多。所以,如果没有平均效率分析的话,计算机科学家可能会错失很多重要的算法。

最后,从前面的讨论中可以了解到,我们不能用最优效率和最差效率求平均数的方法来求得平均效率,虽然这个平均数偶尔会和平均效率一致,但它并不是进行平均效率分析的规范方法。

Reference:Introduction to The Design and Analysis of Algorithms_Anany Levitin

(End_xpjiang)