时间复杂度的通俗讲法

2017-12-23  本文已影响0人  DevWang
时间频度:

一个算法花费的时间与算法中语句的执行次数成正比,我们将算法中的语句执行次数称为语句频度或时间频度,记为T(n)n称为问题的规模.

在时间频度中,当n不断变化时,时间频度T(n)也会不断变化,但有时我们想知道随着问题的规模n的不断增加,运行时间呈现怎样的变化规律,为此,引入了时间复杂度.

时间复杂度:
时间复杂度n²比对

图中4条曲线分别表示4种不同的执行次数表达式,从图中可以看出,只要最高项的阶数相同,4种表达式值受其他项的影响很小,随着n增大,几乎可以忽略不计,甚至可以忽略与最高项相乘的常数

更通俗的讲:时间复杂度是T(n)中受n的变化影响最大的那一项(不包含系数)

最坏时间复杂度和平均时间复杂度

最坏情况下的时间复杂度称最坏时间复杂度。一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。 这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会超过此时间.

常见时间复杂度

常数阶O(1)对数阶O(log₂n)线性阶O(n)线性对数阶O(nlog₂n)平方阶O(n²)立方阶O(n³)k次方阶(n)指数阶O(2ⁿ)

常见时间复杂度比对图

从图中不难看出,选择算法时候应该尽量选择对数阶而非指数阶时间复杂度的算法.

常数阶O(1)
void func(int n) {
    printf("Hello, World!\n"); // 循环体时间复杂度为 O(1)
}
对数阶O(log₂n)
void func(int n) {
    for(int i = 1; i < n; i *= 2) { // 循环次数为 log₂n
        printf("Hello, World!\n"); // 循环体时间复杂度为 O(log₂n)
    }
}
线性阶O(n)
void func(int n) {
    for(int i = 0; i < n; i++) { // 循环次数为 n
        printf("Hello, World!\n"); // 循环体时间复杂度为 O(n)
    }
}
线性对数阶O(nlog₂n)
void func(int n) {
    for(int i = 0; i < n; i++) { // 循环次数为 n
        for(int j = 1; j < n; j *= 2) { // 循环次数为 log₂n
            printf("Hello, World!\n"); // 循环体时间复杂度为 O(nlog₂n)
        }
    }
}
平方阶O(n²)
void func(int n) {
    for(int i = 0; i < n; i++) { // 循环次数为 n
        for(int j = 0; j < n; j++) { // 循环次数为 n
            printf("Hello, World!\n"); // 循环体时间复杂度为 O(n²)
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读