算法-复杂度分析:如何分析、统计算法的执行效率和资源消耗?

整理自极客时间-数据结构与算法之美。原文内容更完整,且有音频。购买地址:

只要讲到数据结构与算法,就一定离不开时间、空间复杂度分析。而且 我个人认为复杂度分析是真个算法的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半

1.为什么需要复杂度分析?

你可能会有些疑惑,我把代码跑一遍,通过统计、监控,就能得到算法执行的时间和占用的内存大小。为什么还要做时间、空间复杂度分析呢?

首先肯定的说,这种评估算法执行效率的方法是正确的。很多书籍管这种方法叫“事后统计法”。但是这种方法有很大的局限性:

  1.  测试结果非常依赖测试环境:如测试环境中的硬件对测试j结果影响很大。
  2. 测试结果受数据规模的影响很大。如小规模的数据 插入排序反而比快速排序快。

所以,我们需要一个不用具体数据来测试,就可以粗略的估算执行效率的方法。

2.大O复杂度表示法

算法的执行效率,粗略的讲,就是算法的执行时间。

例子1:

//这里有段简单的代码,求1到n的累加和。
int cla(int n){
    int sum = 0;
    int i = 1;
    for (;i<=n; i++){
        sum = sum + 1;
    }
    return sum;
}

现在我们来估算下,上述代码的执行时间:

尽管每行代码对应cpu执行的个数、执行的时间都不一样,但是我们这里只是粗略的估计,所以我们可以假设每行代码执行的时间都一样,都为unit_time。在这个假设的基础上,我们进行分析!

第3、4行都执行了一次,第5、6行都执行了n次。所以这段代码总执行2*unit_time+2n*unit_time。可以看出代码的执行时间(T(n))与代码的执行次数成正比。

例2:

int cal(int n){
    int sum = 0;
    int i = 1; 
    int j = 1;
    for(; i<= n ;i++){
        j = 1;
        for(; j <= n ; j++){
            sum = sum + i*j;
        }
    }
}

我们依旧按照例1中的方法进行分析。

第2、3、4行代码都分别执行了一次。第5、6行都循环执行了n次,需要2n*unit_time 的执行时间。第7、8行都执行了n*n次,需要2n*n*unit_time的执行时间。 所以例2的总的执行时间为3*unit_time+2n*unit_time+2n*n*unit_time。

通过两个例子,我们可以得出一个规律:所有代码的执行时间T(n)与每行代码的执行次数n成正比。

我们可以把这个规律总结成一个公式。注意,大 O 就要登场了!

我们来解释一下这个公式。T(n)表示代码的执行时间;n表示数据规模的大小;f(n)表示每行代码执行次数的总和。因为这是一个公式,所以用f(n)表示。公式中的O,表示代码的执行时间T(n)与f(n)表达式成正比。

待续......

猜你喜欢

转载自blog.csdn.net/qq_16399991/article/details/83216400