目录
①算法的时间复杂度(T(n))和O(f(n))的之间的关系(建议反复理解)
我们使用时间复杂度与空间复杂度的目的便是,检验当前算法的效率优不优的问题以及在多个算法中选择出最优算法。
一、时间复杂度
1.衡量算法效率的两种方法
衡量算法效率主要有两种方法:事后统计法和事前分析估算法。
①事后统计法:
事后统计法,需要先将算法实现,然后在对算法执行的时间与占用的空间进行计算统计。
该算法存在种种缺陷,以及不切实际性因素:
1.必须把算法转换为可执行的程序,如果是应用到航天工程、深海勘测、导弹打击等领域,先执行后计算统计显然是不切实际的。
2.计算统计结果受计算机软硬件方面的环境因素影响,若同一段代码,放在单片机上与超级计算机上显然是执行速率不一样的,因此会造成测量不准确的问题。
除此之外,编程语言、编译程序产生的机器指令质量也会有所影响。
②事前分析估算法:
事前分析估算法不依赖于特定的计算机硬件或软件环境,而是关注算法本身的逻辑结构和输入数据的规模。
它的目的是为了比较不同算法处理相同问题时的效率,以及在不同问题规模下算法性能的变化。
事前分析估算法时间复杂度旨在寻找时间花费T(n)与问题规模n之间的函数关系。
2.问题规模和语句频度
①问题规模:
问题规模(n)是算法求解问题输入量的多少,其本质便是问题大小。同一个算法,问题规模越大,相应的算法执行时间越长。
②语句频度:
一个算法的执行时间约等于该算法所有语句执行时间的总和;
其中语句的执行时间则为该条语句的重复执行次数和执行一次所需时间的乘积。
一条语句重复执行的次数被称作语句频度(Frequency Count)
3.时间复杂度的定义
时间复杂度(Time Complexity)是算法运行所需时间的度量,它表示算法执行所需的操作次数或指令数,通常用O表示。时间复杂度T(n)通常表示为算法中基本操作执行次数的总和。
更具体地说,时间复杂度表示的运算时间如何随着问题输入规模的增长而增长,以及一条语句重复执行的次数即语句频度。
在计算时间复杂度时,通常会忽略常数因子和低阶项,只关注算法的增长率。
因此,时间复杂度只考虑随着输入规模增长而导致的性能变化,并忽略具体常数值。
①算法的时间复杂度(T(n))和O(f(n))的之间的关系(建议反复理解)
算法的时间复杂度(T(n))和O(f(n))的之间的关系是一种数学上的渐进关系。
在算法分析中,我们关注的是算法执行时间与问题规模n的函数关系。时间复杂度T(n)通常表示为算法中基本操作执行次数的总和,这个基本操作在不同的算法中可能代表不同的动作。
大O表示法是一种用来描述算法时间复杂度的术语,它定义了算法运行时间随问题输入规模n增长的趋势。
具体来说,如果存在一个函数f(n),使得当问题规模n趋向无穷大时,算法的时间复杂度T(n)与f(n)的增长率相同,也就是说明T(n)/f(n)的极限为一个非零常数,那么我们就可以表示算法的渐进时间复杂度为O(f(n))。
其中c是一个常数。
![](https://img-blog.csdnimg.cn/direct/8e72f570dce44cbe908ebc854a93d50a.png)
在实际应用中,我们通常关注的是最高阶项,因为它在n较大时对总时间的影响最为显著。所以,在确定时间复杂度时,我们通常会忽略常数因子和低阶项,只保留高阶项。
例如,如果一个算法的运行时间为:T(n) = 3n^2 + 2n + 1,那么我们只会关注n^2 这一项,因为随着n的增大,n^2 的增长速度远大于常数项和一次项。因此,该算法的时间复杂度为:O(n^2)。
总结来说,时间复杂度(T(n))和O(f(n))之间的关系反应了算法执行时间随着问题规模增长的趋势,通过大O表示法我们可以忽略掉常数因子和低阶项,只保留最高阶项来化简算法的复杂度表达,从而更容易比较不同算法的性能。
4.时间复杂度分析举例
①求非递归算法的时间复杂度
【例4.1.1】常量阶示例
{a++;b--;c=0}
三条语句频度均为1,算法执行时间与问题规模无关;
算法时间复杂度为T(n)=O(1)。
【例4.1.2】线性阶示例
for(i=0; i<n; i++){
a++;
b=0;
}
循环体内两条基本语句的频度均为f(n)=n;
算法时间复杂度为T(n)=O(n)。
【例4.1.3】平方阶示例
a=0;b=0;
for(i=1;i<=n;i++){
a++;
}
for(z=1;z<=n;z++){
for(j=1;j<=i;j++){
b--;
}
}
基本语句的频度均为f(n)=n+n^2;
算法时间复杂度为T(n)=O(n^2)。
【例4.1.3】立方阶示例
a=1;
for(i=1;i<=n;i++){
for(z=1;z<=i;z++){
for(k=1;k<=z;k++){
a++;
}
}
}
基本语句的频度均为
算法时间复杂度为T(n)=O(n^3)。
【例4.1.3】对数阶示例
for(i=1;i<=n;i=i*2){
a++;
b=0;
}
基本语句的频度均为f(n),则有2^f(n)≤你,f(n)≤log以2为底的n。
算法时间复杂度为T(n)=O(log2n)。
②求递归算法的时间复杂度
请查找递归方面知识。
5.时间复杂度排序
![](https://img-blog.csdnimg.cn/direct/f3829741cdf44f25a30124ae76777245.png)
一般情况下,随着n的增大,T(n)的增长较慢的算法为较优的算法。
因此应尽量可能选择使用多项式阶的算法,而避免使用指数阶的算法。
6.最好、最坏、平均时间复杂度
算法中最好情况下的时间复杂度为最好时间复杂度,指算法计算量可能达到的最小值;
算法中最坏情况下的时间复杂度为最坏时间复杂度,指算法计算量可能达到的最大值;
平均时间复杂度是指算法在所有可能情况下,按照输入实例以等概率出现时,算法计算量的加权平均值。
例:在一维数组中查找某个等于A的元素,并返回其所在位置:
for(i=0;i<n;i++){
if(a[i]==A){
return i+1;
}
else{
return 0;
}
}
如果查找第一个元素即为A,则无论数组规模多大,语句只执行一次,f(n)=1;
如果查找最后一个元素为A,则f(n)=n。
二、空间复杂度
空间复杂度是指算法在执行过程中所需的额外的存储空间的量度。它是对算法的存储空间要求的评估,通常用空间复杂度来衡量算法的效率和性能。
1.额外空间复杂度和总空间复杂度
空间复杂度可以分为两种形式:
-
额外空间复杂度(auxiliary space complexity):指算法执行过程中除了输入和输出所需的额外空间,不包括输入数据占用的空间。通常用来衡量算法执行过程中临时变量、辅助数据结构等所需的额外空间。
-
总空间复杂度(total space complexity):指算法执行过程中所需的总存储空间,包括输入数据占用的空间以及额外空间。总空间复杂度等于输入占用的空间加上额外空间。
空间复杂度通常以符号O表示,表示存储空间的增长趋势。常见的空间复杂度有O(1)、O(n)、O(n^2)等。其中,O(1)表示算法所需的额外空间是常数;O(n)表示算法所需的额外空间与输入规模n成线性关系;O(n^2)表示算法所需的额外空间与输入规模n的平方成正比。
例:
【算法1】
for(i=0;i<n/2;i++){
j=a[i];
a[i]=a[n-i-1];
a[n-i-1]=j;
}
【算法2】
for(i=0;i<n;i++){
b[i]=a[n-i-1];
}
for(i=0;i<n;i++){
a[i]=b[i];
}
算法1仅需另外借助一个变量t,与问题规模n大小无关,空间复杂度为O(1)。
算法2需要另外借助一个大小为n的辅助数组b,空间复杂度为O(n)。
递归的空间复杂度: 空间复杂度=递归调用的深度
三、总结
对于一个算法,时间复杂度与空间复杂度是相互影响的,当追求一个较好的时间复杂度时,可能会导致占用较多的存储空间,即可能会使空间复杂度的性能变差,反之也是如此。
通常情况下,鉴于运算空间较为充足,我们大多数以算法的时间复杂度作为算法优劣的衡量指标。