算法的耗时和语句的执行次数是成正比的,即语句执行越多,耗时越多。这也就是我们引入概念的原因。
2.简单算法的时间复杂度举例
列举一些简单例子的时间复杂度。
O(1)的算法是一些运算次数为常数的算法。例如:
temp=a;a=b;b=temp;
上面语句共三条操作,单条操作的频度为1,即使他有成千上万条操作,也只是个较大常数,这一类的时间复杂度为O(1)。
O(n)的算法是一些线性算法。例如:
sum=0;
for(i=0;i<n;i++)
sum++;
上面代码中第一行频度1,第二行频度为n,第三行频度为n,所以f(n)=n+n+1=2n+1。所以时间复杂度O(n)。这一类算法中操作次数和n正比线性增长。
O(logn) 一个算法如果能在每个步骤去掉一半数据元素,如二分检索,通常它就取 O(logn)时间。举个栗子:
int i=1;
while (i<=n)
i=i*2;
上面代码设第三行的频度是f(n), 则:2的f(n)次方<=n;f(n)<=log₂n,取最大值f(n)= log₂n,所以T(n)=O(log₂n ) 。
O(n²)(n的k次方的情况)最常见的就是平时的对数组进行排序的各种简单算法都是O(n²),例如直接插入排序的算法。
而像矩阵相乘算法运算则是O(n³)。
举个简单栗子:
sum=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
sum++;
第一行频度1,第二行n,第三行n²,第四行n²,T(n)=2n²+n+1 =O(n²)
O(2的n次方) 比如求具有n个元素集合的所有子集的算法
O(n!) 比如求具有N个元素的全排列的算法
时间复杂度按n越大算法越复杂来排的话:常数阶O(1)、对数阶O(logn)、线性阶O(n)、线性对数阶O(nlogn)、平方阶O(n²)、立方阶O(n³)、……k次方阶O(n的k次方)、指数阶O(2的n次方)。
既然说到了这个复杂排序,就必须再多说几句。我们还需要区分算法最坏情况的行为和期望行为。就比如说快速排序,最坏情况运行时间是 O(n²),但期望时间是O(nlogn)。但是我们只要通过一些手段,可以避免最坏情况发生,所以在实际情况中,精心设计的快速排序都能以期望时间运行。
最后再提一下指数的情况。指数算法一般来说太复杂了,所以实际情况下如果不是迫不得已不要用时间复杂度为指数的算法,除非n特别小。