所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比
示例1:
int calc(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum = sum + i;
}
return sum;
}
从 CPU 的角度来看,这段代码的每一行都执行着类似的操作:读数据-运算-写数据。尽管每行代码对应的 CPU 执行的个数、执行的时间都不一样,但是,这里只是粗略估计,所以可以假设每行代码执行的时间都一样,为 unit_time。
即:第2、3行执行时间为一个unit_time,第4、5行分别执行n次,即2*n个unit_time,所以总时间为(2n+2)*unit_time
示例2:
int calc(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;
}
}
}
第2、3、4行执行时间为一个unit_time,第5、6行执行时间为2*n个unit_time,第7、8行执行时间为2*n*n个unit_time,总时间为(2n^2+2n+3)*unit_time
公式:
T(n):代码执行时间。
n:数据规模。
f(n):每行代码执行的次数总和。
O:代码的执行时间T(n)与f(n)成正比。
示例1和示例2分别用公式表示就是和。这就是O时间复杂度表示法,表示的代码执行时间随数据规模增长的变化趋势。所以也叫渐进时间复杂度(asymptotic time complexity),简称时间复杂度。
当时,公式中的低阶、常数、系数都可以忽略,并不影响增长趋势,即最终示例1和实例2表示成为
时间复杂度分析
int i = 8;
int j = 6;
int sum = i + j;
只要代码的执行时间不随n的增长而增长,这样代码的时间复杂度都记作O(1)。或者说,一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行代码,时间复杂度都记作O(1)。
- 、
i=1;
while (i <= n) {
i = i * 2;
}
只要计算出,第三行代码执行的次数。i从1开始取值,依次为:,当时,跳出循环,即,即时间复杂度为
i=1;
while (i <= n) {
i = i * 3;
}
同理,时间复杂度为:。
,忽略常数,即,就可以忽略地址,直接表示成
再循环执行n遍,时间复杂度就为
- 、
int cal(int m, int n) {
int sum_1 = 0;
int i = 1;
for (; i < m; ++i) {
sum_1 = sum_1 + i;
}
int sum_2 = 0;
int j = 1;
for (; j < n; ++j) {
sum_2 = sum_2 + j;
}
return sum_1 + sum_2;
}
m和n是两个数据规模,无法评估谁的量级大,所以不能简单的忽略掉其中一个,所以上面的时间复杂度就为O(m+n)。
同理乘法的就为
空间复杂度分析
空间复杂度:又称渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系。
void print(int n) {
int i = 0;
int[] a = new int[n];
for (i; i <n; ++i) {
a[i] = i * i;
}
for (i = n-1; i >= 0; --i) {
System.out.println(a[i]);
}
}
第2行中,申请了一个空间存储变量i,但是是常量阶的,所以忽略。第3行申请了一个大小为n的int类型的数组,除此之外,剩下的代码没有占用更多空间,所以空间复杂度为。
常见的空间复杂度有:。而O(logn)和O(nlogn)平时基本用不到。
最好、最坏情况时间复杂度
// n 表示数组 array 的长度,在一个无序的数组(array)中,查找变量 x 出现的位置
int find(int[] array, int n, int x) {
int i = 0;
int pos = -1;
for (; i < n; ++i) {
if (array[i] == x) {
pos = i;
break;
}
}
return pos;
}
如果数组中第一个元素就是要查找的变量,则无需进行剩下的数据,时间复杂度就是O(1)。
如果数组中不存在要查找的变量,则时间复杂度为O(n)。
最好情况时间复杂度:在最理想的情况下,执行这段代码的时间复杂度。
最坏情况时间复杂度:在最糟糕的情况下,执行这段代码的时间复杂度。
平均情况时间复杂度
还是上面的代码
要查找变量x在数组中的位置,有n+1种情况:在数组的0~n-1的位置中和不在数组中。
把每种情况需要查找变量的元素累加,再除以n+1,就是需要遍历的平均值:
省略系数,低阶,常量得到平均时间复杂度就是O(n).