1.算法效率评价标准
对于同样的编程问题,使用不同的算法最终的结果是一样的,但计算机计算过程是消耗的时间和空间却不一样,但是我们又不能去计算每个算法用的时间和空间,我们只能通过数学的方法来估算这个算法,这就是时间复杂度和空间复杂度产生的原由。
时间复杂度和空间复杂度也是判断算法效率的重要指标;
时间维度:是执行当前算法所消耗的时间,我们通常使用时间复杂度来描述.个人认为时间复杂度是[评估代码在cpu中的运行总行数]----T(n)=O(f(n))
空间维度:是指执行当前需要占用多少=内存空间,我们通常用空间复杂度来描述.[评估代码在计算机内存中声明单元变量的总个数]-----S(n)=O(n)
2.时间复杂度
我们想要知道一个算法的「时间复杂度」,很多人首先想到的的方法就是把这个算法程序运行一遍,那么它所消耗的时间就自然而然知道了。
这种方式可以吗?当然可以,不过它也有很多弊端。
这种方式非常容易受运行环境的影响,在性能高的机器上跑出来的结果与在性能低的机器上跑的结果相差会很大。
而且对测试时使用的数据规模也有很大关系。再者,并我们在写算法的时候,还没有办法完整的去运行呢。
因此,另一种更为通用的方法就出来了:「 大O符号表示法 」,即 T(n) = O(f(n)) T(n) = O(f(n))
其中f(n) 表示每行代码执行次数之和 而 O 表示正比例关系 这个公式的全称是:算法的渐进时间复杂度
为什么可以这么去简化呢,因为大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。
所以上面的例子中,如果n无限大的时候,T(n) = time(1+2n)中的常量1就没有意义了,倍数2也意义不大。因此直接简化为T(n) = O(n) 就可以了。
常见的时间复杂度量级有:
常数阶O(1)
对数阶O(logN)
线性阶O(n)
线性对数阶O(nlogN)
平方阶O(n²)
立方阶O(n³)
K次方阶O(n^k)
指数阶(2^n)
3.空间复杂度
既然时间复杂度不是用来计算程序具体耗时的,那么我也应该明白,空间复杂度也不是用来计算程序实际占用的空间的。
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用 S(n) 来定义。
空间复杂度比较常用的有:O(1)、O(n)、O(n²),我们下面来看看:
空间复杂度 O(1)
{
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
}
代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
空间复杂度 O(n)
{
int[] m = new int[n]
for(i=1; i<=n; ++i)
{
j = i;
j++;
}
}
这段代码中,第一行new了一个数组出来,这个数据占用的大小为n,
这段代码的2-6行,虽然有循环,但没有再分配新的空间,
因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)