时间复杂度

请原谅我也是一个标题党!

关于时间复杂度和空间复杂度分析的文章其实不少,但大多数都充斥着复杂的数学计算,让很多读者感到困惑,我就不跟大家扯皮了,关于什么是渐近分析、最坏时间复杂度、平均时间复杂度和最好的时间复杂度,以及大 记法等等,大家好好花点儿时间看看严老师的书就会了。

我们从代码和实现的层面讲讲,如何计算你写的代码的时间复杂度?

任何一门语言的逻辑结构无非三种:顺序结构、循环结构和分支结构,但是真正影响到时间复杂度只有循环结构,如果分支结构影响复杂度,也是因为分支内部包含了循环。
时间复杂度分析,这个很多人都不知道,更别谈会了!_i++
循环的实现有 for 和 while 两种形式,但是本质都是一样的,我们接下来均以 for 循环进行说明。

如果一个函数(语句)不包含循环、迭代或非常数时间的函数,则可以认为函数为O(1) 的时间。

// 非循环或者递归语句或函数
int love = 520;

比如交换两个数的 swap() 函数的时间复杂度就是 O(1) :

void swap(int *xp, int *yp) 
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}

一个循环如果仅仅运行常数次,那么时间复杂度也可以当作 O(1) 来处理:

// c 表示一个常量
for(int i = 0; i < c; i++) {
// O(1) 表达式
}

如果循环控制变量 i 递增/递减的步长为一个常数 c,则认为循环的时间复杂度为O(n) 。例如,以下函数的时间复杂度为 O(n) :

// c 是一个正整数常量
for(int i = 0; i < n; i += c) {
// O(1) 表达式
}
-------------------------------
for(int i = n; i > 0; i -= c) {
// O(1) 表达式
}

O(n^c) ,嵌套循环的时间复杂度等于最内层语句的执行次数。例如,下面示例循环的时间复杂度为 O(n ^ 2 ) :

for (int i = 1; i <= n; i += c) {
for (int j = 1; j <= n; j += c) {
// O(1) 表达式
}
}

for (int i = n; i > 0; i -= c) {
for (int j = i+1; j <= n; j += c) {
// O(1) 表达式
}
}

如果循环控制变量 i 乘以或除以一个常数 c,则循环的时间复杂度为 O(log n)量级:

// c 是一个正整数常量
for(int i = 1; i < n; i *= c) {
// O(1) 表达式
}
-------------------------------
for(int i = n; i > 0; i /= c) {
// O(1) 表达式
}

时间复杂度分析,这个很多人都不知道,更别谈会了!_i++_02

int binarySearch(int arr[], int l, int r, int x) 
{
while (l <= r) {
int m = l + (r - l) / 2;
if (arr[m] == x)
return m;

if (arr[m] < x)
l = m + 1;
else
r = m - 1;
}
return -1;
}

时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_03

for(int i = 2; i <= n; i = pow(i, k)) {
// O(1) 表达式或语句
}

如果程序中包含多个循环,又该如何时间复杂性?
如果程序中存在多个连续循环时,时间复杂度为多个单循环的时间复杂度之和。

for (int i = 1; i <= m; i += c) {  
// O(1) 表达式或语句
}
for (int i = 1; i <= n; i += c) {
// O(1) 表达式或语句
}

时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_04

int search(int arr[], int n, int x) 
{
int i;
for (i = 0; i < n; i++) {
if (arr[i] == x)
return i;
}
return -1;
}

时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_05
时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_06
时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_07
时间复杂度分析,这个很多人都不知道,更别谈会了!_时间复杂度_08
时间复杂度分析,这个很多人都不知道,更别谈会了!_i++_09
时间复杂度分析,这个很多人都不知道,更别谈会了!_时间复杂度_10
时间复杂度分析,这个很多人都不知道,更别谈会了!_分支结构_11
时间复杂度分析,这个很多人都不知道,更别谈会了!_时间复杂度_12
时间复杂度分析,这个很多人都不知道,更别谈会了!_i++_13
当然这也只是一个比较粗略的概括,时间复杂度的分析无定法,仅仅是大家的一个共识而已,最好的方法是,将你的代码结合数据跑起来,计算它的运行时间,但是这也需要大家规定设备的型号和运行内存等等硬件。

谁说深究不是一种品质呢?如果你真的对时间复杂度和空间复杂度感兴趣,那就研究下去!!!