渐近记号
使用渐近记号的函数刻画算法的运行时间。
渐近记号包括:
(1)Θ(theta):相当于"=",给出函数大的渐近上界和下界。
(2)O(大欧):相当于"<=",给出函数的渐近上界
(3)o(小欧):相当于"<",给出函数的非渐近紧确上界
(4)Ω(大omega):相当于">=",给出函数的渐近下界
(5)ω(小omega):相当于">",给出函数的非渐近紧确下界
渐近记号的定义:
前提是
f
(
n
)
f(n)
f(n),
g
(
n
)
g(n)
g(n)渐近非负.
1)
f
(
n
)
=
Θ
(
g
(
n
)
)
f(n)=\Theta(g(n))
f(n)=Θ(g(n))
2)
f
(
n
)
=
O
(
g
(
n
)
)
f(n)=O(g(n))
f(n)=O(g(n))
3)
f
(
n
)
=
Ω
(
g
(
n
)
)
f(n)=\Omega(g(n))
f(n)=Ω(g(n))
4)
f
(
n
)
=
o
(
g
(
n
)
)
f(n)=o(g(n))
f(n)=o(g(n))
5)
f
(
n
)
=
ω
(
g
(
n
)
)
f(n)=ω(g(n))
f(n)=ω(g(n))
算法的效率主要由以下两个复杂度来评估:
时间复杂度:算法的时间复杂度,也就是算法的时间量度,评估执行程序所需的时间,通常使用大O记法。可以估算出程序对处理器的使用程度。
空间复杂度:评估执行程序所需的存储空间。可以估算出程序对计算机内存的使用程度。
设计算法时,一般是要先考虑系统环境,然后权衡时间复杂度和空间复杂度,选取一个平衡点。不过,时间复杂度要比空间复杂度更容易产生问题,因此算法研究的主要也是时间复杂度,不特别说明的情况下,复杂度就是指时间复杂度。
时间复杂度
时间复杂度的计算并不是计算程序具体运行的时间,而是算法执行语句的次数。
常见的时间复杂度有:
常数时间复杂度O(1),
线性时间复杂度O(n),
对数时间复杂度O(log2 n),
线性对数阶O(n log2 n),
平方阶O(n^2),
立方阶O(n^3)
k次方阶O(n^K),
指数阶O(2^n)。
阶乘O(n!)
时间复杂度曲线
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!) <O(
n
n
n^n
nn)
时间复杂度的计算(忽略系数):
1.常数阶O(1)
如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
int x=1;
while (x <10)
{
x++;
}
该算法执行次数是10,是一个常数,用时间复杂度表示是O(1)。
2.k次方阶O(n^K)
当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
;
}
}
该算法for循环,最外层循环每执行一次,内层循环都要执行n次,执行次数是根据n所决定的,时间复杂度是O(n^2)。
3.对数阶O(logN)
int i = 1;
while(i<n)
{
i = i * 2;
}
从上面代码可以看到,在while循环里面,每次都将 i 乘以 2,乘完之后,i 距离 n 就越来越近了。我们试着求解一下,假设循环x次之后,i 就大于 2 了,此时这个循环就退出了,也就是说 2 的 x 次方等于 n,那么 x = log2^n
也就是说当循环 log2^n 次以后,这个代码就结束了。因此这个代码的时间复杂度为:O(logn)
空间复杂度
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
空间复杂度比较常用的有:O(1)、O(n)、O(n²),我们下面来看看:
1.空间复杂度 O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)
举例:
int i = 1;
int j = 2;
++i;
j++;
int m = i + j;
代码中的 i、j、m 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
参考资料:
https://zhuanlan.zhihu.com/p/50479555
https://www.zhihu.com/question/21387264
https://blog.csdn.net/qq_37886086/article/details/90725931