在开发的时候,我们如何评估一个算法的好坏,如何描述一个算法运行效率的高低呢?通俗一点的表达方法就是程序执行快
或慢
,但是这只是一种较为宽泛的描述,我们如何直观科学的用的描述它呢?
有同学可能会说,用其运行时间不就可以很好很直观的描述它了。不过,不同的语言,不同的编译器,不同的CPU来说,对程序的处理的时间是不同的,我们无法单单用运行时间来描述某个算法执行效率。另外,当需要处理的数据增长时,算法的基本操作要重复执行的次数也会增长,对于不同的算法的增长的速度也不一样。
数学果然是个不错的工具,为了描述算法的运行时间的增长情况,我们可以用不同数学公式来分析。在计算机科学上,我们是有专门的术语来表征算法的效率,就是今天要和大家一起学习的大O表示法。大O并不是表示算法运行需要多长时间,它表示的是算法运行时间的增速,即算法的运行时间以不同的速度增加,也叫渐进时间复杂度。
我们可以用下面的表达式来表示:
T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) T(n)=O(f(n))
通常主要有以下几种表达式来描述时间复杂度:
- O(1):常量时间
- O(n):线性时间
- O(log n):对数时间
- O(n^2):二次方时间
- O(2^n):指数时间
- O(n!):阶乘时间
每种时间复杂度有所不同,下面我们一起来详细了解这几种时间复杂度。
O(1)
Q(1)
表示常量时间复杂度,当给定大小为n的输入,无论n为何值,最后算法执行的时间是个常量。举个例子:
int func(int n)
{
n++;
return n*2;
}
上面的程序中,无论输入n的值如何变化,程序执行时间始终是个常量。我们简化处理一下,假如函数中每行语句的执行时间是1,则执行时间的数学表达式:
f ( n ) = 2 f(n) = 2 f(n)=2
无论n为多大,最后的执行时间都是2这个固定值。虽然是运行时间为2,但是这里我们也用O(1)
来表示,这里的1代表是一个常数。
O(n)
O(n)
表示线性时间复杂度,算法的执行时间随着输入n的大小成线性变化。
int func(int n)
{
int sum = 0;
for(int i=0; i<n; i++)