一个算法的好坏,是从两方面进行衡量的,一个是时间复杂度,一个是空间复杂度。下面我将分别介绍这两个概念。
1.时间复杂度
时间复杂度,指的是算法的执行时间,但是这个时间并不是程序运行的时间,而是算法执行语句的次数。
常见的时间复杂度有:
常数阶
O
(
1
)
O(1)
O(1),
对数阶
O
(
l
o
g
2
n
)
O(log_{2}n)
O(log2n),
线性阶
O
(
n
)
O(n)
O(n),
线性对数阶
O
(
n
l
o
g
2
n
)
O(nlog_{2}n)
O(nlog2n),
平方阶
O
(
n
2
)
O(n^2)
O(n2),
立方阶
O
(
n
3
)
O(n^3)
O(n3),…, k次方阶
O
(
n
k
)
O(n^k)
O(nk),
指数阶
O
(
2
n
)
O(2^n)
O(2n)
随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
整个算法的执行时间与基本操作重复执行的次数成正比。
基本操作重复执行的次数是问题规模n的某个函数f(n),于是算法的时间量度可以记为:T(n) = O(f(n))
计算时间复杂度的方法:
(1) 如果算法的执行时间不随着问题的规模n的增长而增长,即使算法中有上千条语句,执行时间也只是一个比较大的常数。此类算法的时间复杂度为O(1);
i = 100000;
while(i--) {
printf("hello");
}
该算法中的第三行是基本操作,执行次数为100000次,是常数,因此时间复杂度为 O ( 1 ) O(1) O(1)
(2) 当有多个循环嵌套时,算法的时间复杂度是由嵌套层数最多的循环语句的语句频度决定的
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
;
}
}
该算法for循环,最外层循环每执行一次,内层循环都要执行n次,执行次数是根据n所决定的,时间复杂度是 O ( n 2 ) O(n^2) O(n2)。
(3) 还有的算法需要考虑循环的条件,初始状态等等。
2.空间复杂度
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。
空间复杂度(SpaceComplexity)是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。
算法本身所占用的存储空间取决于算法本身的长短,输入输出数据所占用的空间取决于要解决的问题,是通过参数表调用函数传递而来,只有辅助变量是算法运行过程中临时占用的存储空间,与空间复杂度相关
空间复杂度的计算方法:
(1)通常来说,只要算法不涉及到动态分配的空间,以及递归、栈所需的空间,空间复杂度通常为0(1)
(2)递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间
对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。