1.0:前言
我们在评判一个算法的优劣时,即需要考虑时间资源还要考虑空间资源 。因此,时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。
算法的优劣,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。
2.0:时间复杂度
2.1:定义:
在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,只有你把你的程序放在机器上跑起来,才能知道。所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度
2.2:理解:
时间复杂度从整体算法的逻辑和思想出发,研究判断算法中最能体现算法思想的语句执行的次数,这种次数可以用数学函数表达式表示出来。称为时间复杂度。找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。
2.3:大O渐近表示法:
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。
2.4:大O渐近表示法规则:
1.常数次为
2.保留最高阶层的项,如果最高阶层有多个,则需要保留所有的最高阶,但不管有多少个最高阶,都需要去掉系数
3.取算法最坏的情况
4.简写成
规则解释:
1.并不表示算法只进行了一次,而表示算法执行了常数次。
2.时间复杂度是算法的一个保守预期。类似于数学中的无穷极限,当未知量趋近于无穷时,最高次对整体的影响最大,因此,我们只取对算法影响最大的项。
3.对于要去掉最高次前的系数:采用极限的思想,当未知量趋近于无穷(指正无穷,次数都为正数)时,前面的系数对整体的影响是不大的。
4.取最坏的情况:时间复杂度是一个保守预期,相同的算法,可能传入的数值的顺序有所差异,就会影响这个算法的效率,如果按照最好的情况来计算,那么如果数据非常庞大的话,我们就无法确保算法效率的精准性,如果取折中(中间情况)的方法,还是无法保证准确性。因此,我们应该取算法的最坏情况。
3.0:例题
//计算时间复杂度
void Func1(int N)
{
int count = 0;
for (int k = 0; k < 2 * N ; ++ k){
++count;
}
int M = 10;
while (M--){
++count;
}
printf("%d\n", count);
}
从Func1中提取的数学表达式为:,也就是说for语句执行2N次while语句执行10次
通过大O渐近表示法规则,保留最高项并且去掉系数,时间复杂度为。
//计算时间复杂度
void Func2(int N, int M)
{
int count = 0;
for (int k = 0; k < M; ++ k){
++count;
}
for (int k = 0; k < N ; ++ k){
++count;
}
printf("%d\n", count);
}
从Func2中提取的数学表达式为:,由于我们无法确定M和N的量级,所以接下来对
进行分类讨论
1.如果M的量级远大于N时 此时N对整体的影响不大 时间复杂度为
2.如果M和N属于同一个量级时 此时M+N就可以表示为2N或2M 时间复杂度为或
3.如果N的量级远大于M时 此时M对整体的影响不大 时间复杂度为
//计算时间复杂度
void Func3(int N)
{
int count = 0;
for (int k = 0; k < 100; ++ k){
++count;
}
printf("%d\n", count);
}
从Func3中提取的数学表达式100,数学表达式为常数时,时间复杂度为
//计算时间复杂度
long long Fac(size_t N)
{
if(0 == N)
return 1;
return Fac(N-1)*N;
}
从Fac函数是用递归求N的阶乘,通过它的思想Fac(N)调用Fac(N-1),Fac(N-1)调用Fac(N-2) 以此类推一直调用到Fac(0),一共调用了N+1次,所以时间复杂度
//计算时间复杂度
long long Fib(size_t N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}
Fib(N)调用Fib(N-1)和Fib(N-2)
Fib(N-1)调用Fib(N-2)和Fib(N-3)
Fib(N-2)调用Fib(N-3)和Fib(N-4)
.............
直到调用到Fib(2)Fib(1) Fib(0)收尾,像这样的第一次调用2个,第二次调用4个,第三次调用8个..............
我们发现,这是一个首项为1(进入Fib(N))公比为2的等比数列,通过求和公式计算出和为
,再利用大O渐近表示规则,时间复杂度是