时空复杂度分析
数据结构和算法要解决的问题就是让代码运行得更快 , 让存储空间占得更少 , 所以时间和空间复杂度的分析是很重要的 .
那么究竟该如何分析 ?
大 O 复杂度表示法
我们经常会看到 O(1) O(n) O(logn) 这些时空复杂度的表示
其实这就是 大 O 复杂度表示法
, 它并不表示代码执行真正需要的时间 , 而是一种随着数据规模增长的趋势 , 其中 n 就是数据规模的大小 .
比如 n = 100 , 那么 O(n) 时间复杂度需要的时间可以假设为 100 s , 而 O(logn) 时间复杂度需要的时间就是 10 s , 差距一下就体现出来了 .
看下面这段代码
int cal(int n)
{
int sum = 0;
int i = 1;
for (; i <= n; ++i)
{
sum = sum + i;
}
return sum;
}
功能是求 1 - n 的累加和, 假设执行一行代码的时间为一个 run_time
那么 3 4 两行代码执行用时为 2*run_time
而 5 7 两行代码都执行了 n 次, 所以需要的时间为 2n*run_time
于是整个代码运行的时间 T(n) = (2+2*n)*run_time
从这里我们可以看出, 整个代码运行的时间 T(n) 和每行代码运行的次数 n 成正比
设 f(n) = 2+2*n
, 即每行代码运行次数的总和, 因为我们只是估算一个增长趋势, 而常数和系数不会对增长趋势产生什么影响, 所以可以简写为 f(n) = n
则有 T(n) = O(f(n))
, 即表示: 代码执行时间T(n)和代码执行次数f(n)成正比
则上面代码的时间复杂度可以表示为 O(n)
如何快速估算一段代码的时间复杂度?
1, 只关注循环执行次数最多的一段代码
2, 总的复杂度 = 复杂度量级最高的那段代码的复杂度
3, 嵌套代码的复杂度 = 嵌套内外代码复杂度的乘积
举几个例子说明一下:
int cal(int n)
{
int sum_1 = 0;
int p = 1;
for (; p <= 100;