什么是时间复杂度
算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。
一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度,记为T(n),那么其对应的时间复杂度则记为O(f(n))。
常见的时间复杂度量级
- 常数阶O(1)
- 对数阶O(logN)
- 线性阶O(n)
- 线性对数阶O(nlogN)
- 平方阶O(n²)
- 立方阶O(n³)
- K次方阶O(n^k)
- 指数阶O(2^n)
上面的量级从上至下依次的时间复杂度越来越大,执行的效率越来越低。
即:O(1) < O(logN) < O(n) < O(nlogN) <O(n²) < O(n³) < O(n^k) < O(2^n)
如下图所示:
时间复杂度分析
一般分为以下三种情况:
- 最坏情况(Worst Case):任意输入规模的最大运行时间。(Usually)
- 平均情况(Average Case):任意输入规模的期待运行时间。(Sometimes)
- 最佳情况(Best Case):通常最佳情况不会出现。(Bogus)
例如,在一个长度为 n 的列表中顺序搜索指定的值,则
- 最坏情况:n 次比较
- 平均情况:n/2 次比较
- 最佳情况:1 次比较
而实际中,我们一般仅考量算法在最坏情况下的运行情况,也就是对于规模为 n 的任何输入,算法的最长运行时间。这样做的理由是:
一个算法的最坏情况运行时间是在任何输入下运行时间的一个上界(Upper Bound)。
对于某些算法,最坏情况出现的较为频繁。
大体上看,平均情况通常与最坏情况一样差。
同时我们也应该忽略掉低阶参数的影响,而关注最高阶的增加趋势,比如T(n) = 5n^3+ 3n^2 + 666
的趋势就可以看作为 T(n) = Θ(n3)
。