算法时间复杂度
事前预估算法时间开销(T)与问题规模n的关系。 T = T(n)
算法1.逐步增加型爱你
#include <stdio.h>
void loveYou(int n) {
int i = 1;//1
while (i <= n) {//2
i++;//3
printf("I Love You %d\n", i);//4
}
printf("I Love You More Than %d\n", n);//5
}
int main() {
loveYou(3000);
}
语句频度:1--1次 2--3001次 3,4--3000次 5--1次
T(3000) = 1 + 3001 + 2 * 3000 + 1
时间开销与问题规模n的关系:T(n) = 3n + 3
T1(n) = 3n + 3 ≈ n
T2(n) = n^2 + 3n + 1000 ≈ n^2
T3(n) = n^3 + n^2 + 9999999 ≈ n^3
当问题规模n足够大的时候,我们可以忽略掉表达式中更低阶的部分
结论:一个算法的时间开销表达式,我们只需要表示阶数最高的部分就可以了
T1(n) = O(n)
T2(n) = O(n^2)
T3(n) = O(n^3)
大O表示“同阶”,同等数量级。即:当n->∞时,二者之比为常数
数量级大小比较:
O(1) < O() < O(n) < O() < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
常对幂指阶 常 < 对 < 幂 < 指 < 阶
算法2.嵌套循环型爱你
#include <stdio.h>
void loveYou(int n) {
int i = 1;
while (i <= n) {
i++;
printf("I Love You %d\n", i);
for (int j = 1;j <= n;j++) {
printf("I am Iron Man\n");
}
}
printf("I Love You More Than %d\n", n);
}
时间开销与问题规模n的关系:T(n) = O(n) + O(n^2) = O(n^2)
结论1:顺序执行的代码只会影响常数项,可以忽略
结论2:只需挑循环中的一个基本操作分析它的执行次数与n的关系即可
结论3:如果有多层嵌套循环,只需关注最深层循环循环了几次
算法3.指数递增型爱你
#include <stdio.h>
void loveYou(int n) {
int i = 1;
while (i <= n) {
i = i * 2;
printf("I Love You %d\n", i);
}
printf("I Love You More Than %d\n", n);
}
时间开销与问题规模n的关系:T(n) = O()
算法4.搜索数字型爱你
#include <stdio.h>
void loveYou(int flag[], int n) {
printf("I Am Iton Man\n");
for (int i = 0;i < n;i++) {
if (flag[i] = n) {
printf("I Love You %d\n", n);
break;
}
}
}
计算上述算法的时间复杂度T(n)
最好情况(一般不考虑):元素n在第一个位置 --最好时间复杂度T(n) = O(1)
最坏情况:元素n在最后一个位置 --最坏时间复杂度T(n) = O(n)
平均情况:假设元素n在任意一个位置的概率相同为1/n --平均时间复杂度T(n) = O(n)