比较的理论分析

时间:2015-02-01 23:41:47

标签: performance algorithm sorting

我首先要求开发一个简单的排序算法,按递增顺序对整数数组进行排序并将其放入代码中:

int i, j;

    for ( i = 0; i < n - 1; i++)
    {
        if(A[i] > A[i+1])
            swap(A, i+1, i);

        for (j = n - 2; j >0 ; j--)
            if(A[j] < A[j-1])
                swap(A, j-1, j);
    }

现在我有了排序功能,我要求对算法的运行时间进行理论分析。它说答案是O(n ^ 2),但我不太确定如何证明这种复杂性。

到目前为止我所知道的是第一个循环从0到n-1,(所以n-1次),第二个循环从n-2到0,(所以n-2次)。

执行递归关系:

let C(n) = the number of comparisons
for C(2) = C(n-1) + C(n-2)
         = C(1) + C(0)
    C(2) = 0 comparisons?
    C(n) in general would then be: C(n-1) + C(n-2) comparisons?

如果有人可以一步一步指导我,那将非常感激。

2 个答案:

答案 0 :(得分:1)

在进行“真正的”大O时间复杂度分析时,选择您计算的一个操作,显然是主导运行时间的操作。在你的情况下你可以选择比较或交换,因为最坏的情况会有很多交换吗?

然后计算这将被引发的次数,缩放到输入。因此,在您的情况下,您的分析非常正确,您只需这样做:

C = O((n - 1)(n - 2)) = O(n^2 -3n + 2) = O(n^2)

我通过推理代码中的数据流来得出这些数字。你有一个外部for循环迭代对吗?在for循环中,你有另一个for循环迭代。第一个for循环迭代n - 1次,第二个for循环n - 2次。由于它们是嵌套的,实际的迭代次数实际上是这两个的乘法,因为对于外部循环中的每次迭代,整个内部循环都会运行,进行n - 2次迭代。

正如您可能知道的那样,在进行时间复杂性分析时,您总是会删除除主导词之外的所有术语。

关于最坏情况的复杂性和平均情况,下限,还有很多要补充的内容,但这有望让您掌握如何推理大O时间复杂度分析。

我已经看到了许多用于实际分析表达式的不同技术,例如你的递归关系。但是我个人更喜欢只是推理代码。很少有算法具有硬上限来计算,另一方面下界通常很难计算。

答案 1 :(得分:0)

您的分析是正确的:外部循环进行n-1次迭代。内循环使n-2

因此,对于外部循环的每次迭代,您在内部循环上进行n-2次迭代。因此,步骤总数为(n-1)(n-2) = n^2-3n+2

主导术语(在大O分析中最重要的)是n^2,因此你得到O(n^2)运行时。

在这种情况下,我个人不会使用递归方法。编写递推方程通常对递归函数很有帮助,但是在这样的简单算法中,有时它更容易查看代码并做一些简单的数学运算。