二元搜索的最坏情况复杂度

时间:2014-12-08 18:33:50

标签: algorithm search time-complexity binary-search amortized-analysis

对于我们正在寻找的元素出现的2 ^ n-1个元素的排序数组的二进制搜索,最终情况下的最终时间复杂度是多少?

在我的期末考试中找到了这个。我甚至无法弄清楚为什么我们要为二进制搜索分配时间复杂度,因为最坏的情况是O(log n)。根据我的说明,摊销成本计算算法的上限,然后将其除以项目数,因此不会像最坏情况时间复杂度除以n那样简单,意味着O(log n )/ 2 ^ N-1?

供参考,这是我一直在使用的二进制搜索:

public static boolean binarySearch(int x, int[] sorted) {
    int s = 0; //start
    int e = sorted.length-1; //end

    while(s <= e) {
        int mid = s + (e-s)/2;
        if( sorted[mid] == x )
            return true;
        else if( sorted[mid] < x )
            start = mid+1;
        else
            end = mid-1;
    }
    return false;
}

2 个答案:

答案 0 :(得分:0)

老实说,我不确定这意味着什么 - 我没有看到摊销如何与二元搜索互动。

也许问题是询问成功的二元搜索的平均成本是多少。您可以想象二进制搜索数组的所有n个元素并查看此类操作的平均成本。在这种情况下,有一个元素,搜索产生一个探针,两个搜索产生两个探针,四个产生三个探针,等等。这平均为O(log n)。

希望这有帮助!

答案 1 :(得分:0)

iAmortized cost是所有可能查询的总成本除以可能的查询数。根据您对未能找到项目的查询的计算方式,您将获得略有不同的结果。 (要么根本不计算它们,要么计算缺失项目可能存在的每个间隙的一个。)

因此,搜索2 ^ n - 1个项目(仅作为保持数学简单的示例),您可以在第一个探测器上找到一个项目,在第二个探测器上找到2个项目,4个在第三个探针,第n个探针上的... 2 ^(n-1)。缺失项目有2 ^ n个“缺口”(记住将两端计为缺口)。

使用您的算法,在探针k上查找项目需要进行2k-1次比较。 (对于kth之前的每个k-1探测器,这是2比较,加上对于==的测试返回true的一个。)搜索不在表中的项目需要进行2n次比较。

我会留给你做数学运算,但是当我看到以这种方式编码的二进制搜索时,我不能不表达我的烦恼。考虑:

public static boolean binarySearch(int x, int[] sorted {
    int s = 0; // start
    int e = sorted.length; // end

    // Loop invariant: if x is at sorted[k] then s <= k < e

    int mid = (s + e)/2;
    while (mid != s) {
        if (sorted[mid] > x) e = mid; else s = mid;
        mid = (s + e)/2; }
    return (mid < e) && (sorted[mid] == x); // mid == e means the array was empty
    }

当你点击你正在寻找的项目时,你不会使循环短路,这看起来像是一个缺陷,但另一方面,你只对你看到的每个项目进行一次比较,而不是两次比较在每个不匹配的项目上。由于所有项目中有一半是在搜索树的叶子上找到的,因此看起来像缺陷的东西最终会成为主要收获。实际上,使环路短路有利的元件数量仅仅是阵列中元件数量的平方根。

通过算术计算,计算摊销的搜索成本(计算“成本”作为与排序[mid] 的比较次数,你会发现这个版本的速度大约是其两倍。它也有不变的成本(±1比较),这取决于数组中的项目数量,而不是在哪里或甚至找到项目。不是那么重要。