效率分析
时间效率
假设:洗一个盘子需要30秒,烘干一个盘子也需要30秒,那么洗完n个盘子加烘干需要多少分钟?
Tn个盘子 = n x (30秒洗+30秒烘干) = 60n 秒
用函数表达就是:
f(x) = 60x
又假设在洗一个盘子时,总会溅水到之前的盘子上,也就是要烘干之前的所有盘子。每洗一个盘子30秒,花30秒烘干最后一个盘子,花30x2秒烘干倒数第二个盘子,花费90秒烘干倒数第三个盘子,以此类推。
Tn = n x(30秒洗) + ( ∑ i = 1 n ( i × 30 ) ) \displaystyle \left( \sum_{i=1}^n (i×30) \right) (i=1∑n(i×30))
算术等式 ( ∑ i = 1 n i = n ( n + 1 ) 2 ) \displaystyle \left( \sum_{i=1}^ni= \frac{n(n+1)}{2} \right) (i=1∑ni=2n(n+1))使上面函数变为:
T n = 30 n + 30 n ( n + 1 ) 2 = 15 n 2 + 45 n 秒 Tn=30n + \frac{30n(n+1)}{2} = 15n^2 + 45n 秒 Tn=30n+230n(n+1)=15n2+45n秒
如果要洗30个盘子,第一种花费30分钟,而第二种粗心的方法要用2447.5分钟,而且这个时间随着数量会越来越大,这就是我们考虑的时间复杂度。
增长函数和大O记法
- 首先我们在分析算法时,需要先确定的就是该问题的大小。就洗盘子而言就是洗的个数,如果只洗一个,他们是没有区别的。
- 确定有效的空间和时间。这是我们在实际应用中最应该考虑的点,算法最终目的就是保证我们程序能保证在有效的运行时间内。
一个任务的总花费时间,是根据该任务的执行次数相关。
增长函数
表示问题大小和我们希望最优化的值之间的关系。该函数表示了时间复杂度和空间复杂度。
15
n
2
+
45
n
15n^2+45n
15n2+45n就是增长函数
。
但是我们在实际应用中更应该考虑的是渐进复杂度,也就是n随着个数的增长而增长的时间。渐进复杂度被叫做阶次。
15
n
2
+
45
n
15n^2+45n
15n2+45n在整个等式中,当n非常大时,45n对整个算法的影响很低, 所以阶次
n
2
n^2
n2就是它的时间复杂度,我们记做O(n2)。
而增长函数的执行性时间恒定为O(1)
时间复杂度分析
循环的复杂度
如果一个普通的for循环,且它的循环体里复杂度为O(1)时,那么他们的复杂度为O(n)。
for(int a=1;a<=n;a++){
/*复杂度O(1)*/
}
对数级复杂度
即循环体中对步进a做了每次乘以2的操作,所以总共循环次数为 O ( l o g ( n ) ) O(log(n)) O(log(n)),在程序中如果我们的对数函数没有写底,默认是2,即 O ( l o g 2 n ) O(log_2n) O(log2n)。在数学中是e。
for(int a=1;a<=n;a++){
/*复杂度O(1)*/
a *= 2;
}
嵌套循环复杂度
如果循环体中的复杂度为O(1),那么双层for循环的时间复杂度为O(n2)。