时间复杂度&空间复杂度

对于程序而言,随着输入数据的扩大,程序相应处理时间也相应增长。描述算法的执行时间,将算法执行时间的变化趋势描述为输入规模的一个函数。称作时间复杂度(time complexity)记作 T(n)所谓算法的复杂度分析,其实就是针对算法的基本操作数进行比较。基本操作数就是算法最本质的操作,例如排序算法的比较

由于不同操作系统编译程序的差异性,同一程序在不同系统上的运行时间不尽相同,所以我们将总时间细分,通过累计计算程序每条语句的执行时间,再将时间求和,所得的便是总时间T(n)

大O记号

首先关注T(n)的上界,对于任一的T(n),总是存在一个值,使得:

\(T(n) \leq C * f(n)\)

我们记该上界为O(n),于是有:

\(O(f(n)) = O(C*f(n))\)

很明显,为了方便分析,假设T(n)是一个高次函数。对于一个高次函数,可以直接忽略常数C和其他的低次项,所以我们可以得到如下的性质:

\(O(f(n)) = O(C*f(n))\)

所以可以省略最高次方前的常数项。

对于任意常数, a > b > 0,有:

\(O(n^a + n^b) = O(n^a)\)

举个例子

void bubbleSort(int group[],int n) 
{
    bool issorted = false;
    while(!issorted) {
        issorted = true;
        for(int i = 1; i <= n; i++) {
            if(group[i-1] > group[i]) {
                swap(group[i-1],group[i]);
                issorted = false;
            }
        }
        n--;
    }
}

观察上面的冒泡排序算法,找到它的时间复杂度。

观察,可知该算法时间复杂度不超过

\(O(2*(n-1)^2)\)

化简:

\(O((n-1)^2)\)

再化简:

\(O(n^2)\)

我们就找到了它的时间复杂度

最好,最坏情况

上面的计算方法,实际上是对于时间长度大小的最保守估计,显然,任何情况都不会超出这个值。

但我们仍然不能排除更好的,更坏的情况,需要具体问题具体分析。例如采用加权平均的方法,得到理想结果。

  • 最好情况

    存在一个常数C和某个函数G(n),使得:

    \(T(n) \geq C * g(n)\)

    就可认为,n足够大后,G(n)给出了T(n)的渐进下界

    \(T(n) = \Omega(g(n))\)

  • 中间情况

    存在常数\(C_1\),\(C_2\) ,使得:

    \(C_1 * h(n) \leq T(n) \leq C_2 * h(n)\)

    可以记作:

    \(T(n) = \Theta(h(n))\)

最后,我们可以通过一张照片直观的看出其中的区别:

posted @ 2022-04-25 20:26  は?無理です!  阅读(64)  评论(0)    收藏  举报