算法的时间复杂度
时间复杂度的概念:
时间复杂度是同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率,算法分析的目的在于选择合适算法和改进算法。计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间。这是一个关于代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况。
求解算法的时间复杂度,具体步骤是:
1、找出算法中的基本语句。算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体;
2、计算基本语句执行次数的数量级。只需要计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数,这样能够简化算法分析,并且使注意力集中在最重要的增长率上。
3、用大写字母O表示算法的时间性能。将基本语句执行次数的数量级放入大写字母O中,如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加,例如:
//时间复杂度为O(n) for(i=1;i<=n;i++){ x++ } //时间复杂度为O(n^2) for(i=1;i<=n;i++){ for(i=j;j<=n;j++){ x++; } } //整个算法的时间复杂度为O(n+n^2)=O(n^2)
常见的时间复杂度有:
常数阶O(1),对数阶O(log2n),线性阶O(n), 线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3),..., k次方阶O(nk),指数阶O(2n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
时间复杂度知识点一:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数,此类算法的时间复杂度是O(1)。例如:
x=91; y=100; while(y>0){ if(x>100){ x=x-10; y--; } else{ x++; } }
解析:T(n)=O(1)
这个程序看起来有点吓人,总共循环运行了1100次,但是我们并没有看到n。因为这段程序的运行是和n无关的,就算它在循环一万年,也只是一个常数阶的函数。
时间复杂度知识点二:
int num1,num2; for(int i=0;i<n;i++){ num1 +=1; for(int j=1;j<=n;j *=2){ num2 +=num1; } }
解析:T(n)=O(n*log2^n)
语句int num1, num2;的频度为1;
语句i=0;的频度为1;
语句i<n; i++; num1+=1; j=1; 的频度为n;
语句j<=n; j*=2; num2+=num1;的频度为n*log2^n;(j的每一步是 j *= 2 ,那么需要多少次能到达n呢?反推得到就是 log2^n 次)
T(n) = 2 + 4n + 3n*log2n
忽略掉T(n)中的常量、低次幂和最高次幂的系数
f(n) = n*log2n
lim(T(n)/f(n)) = (2+4n+3n*log2n) / (n*log2n)
= 2*(1/n)*(1/log2n) + 4*(1/log2n) + 3
当n趋向于无穷大,1/n趋向于0,1/log2n趋向于0,所以极限等于3。
得:T(n) = O(n*log2n)