由一个类似于二分搜索的算法引出了对复杂度的分析问题。
想来想去,也不知道如何证明。
这也说明自己对算法的理解不到位的地方,也是如何证明,如何分析复杂度,这里进行一次大补。
如果用主定理的话,又体现不出对算法的深入理解吧。而且算法证明最好不要用主定理,不能体现水平吧。
补充一:
算法复杂度分为时间复杂度和空间复杂度。对于时间复杂度,可以理解为程序运行的次数 也就是f(n),因此,算法的时间复杂度记做:T(n)=O(f(n))。
首先证明一下二分搜索的复杂度:
从上面的思路想,由N来说,第一次比较后 N/2 ,第二次比较后为N/4,这也经过K次后停止,此时为N/(2^K)次。
最后一步 所以,N/(2^K) = 1。
要求执行次数,即K,则K = logn。
证毕。
至于如何求一个算法的时间复杂度的问题,笔试常考。这里借鉴一下他人的算法分析方法:
根据定义,可以归纳出基本的计算步骤
1. 计算出基本操作的执行次数T(n)
基本操作即算法中的每条语句(以;号作为分割),语句的执行次数也叫做语句的频度。在做算法分析时,一般默认为考虑最坏的情况。
2. 计算出T(n)的数量级
求T(n)的数量级,只要将T(n)进行如下一些操作:
忽略常量、低次幂和最高次幂的系数,令f(n)=T(n)的数量级。
3. 用大O来表示时间复杂度
当n趋近于无穷大时,如果lim(T(n)/f(n))的值为不等于0的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n))。
记住算法的复杂度一定是与K=f(n)有关的,也就是常量语句的执行次数。
例如:
int num1, num2;
for(int i=0; i<n; i++){
num1 += 1;
for(int j=1; j<=n; j*=2){
num2 += num1;
}
}
1.
K2 = n+1
K3 = n
k4 =>1 2 4 8 … 2^K4 => 2^k4 = n(n时结束) 所以k4 = log n
K5 = logn
所以总体执行次数T(n) = k2+k3+k2*(k4+k5)= n+1 + n + n*(2 logn) = 2n+1 + n*(2logn)
2.
f(n) = 对T(n)做:忽略常量、低次幂和最高次幂的系数,令f(n)=T(n)的数量级。
3.验证
lim(T(N)/f(n)) = (2n+1 + n*(2logn) ) / n*(logn) = 2.
所以复杂度 是 O(f(n))=O(nlogn)