// 时间复杂度 O(log(N))
long int Pow(long int X,unsigned int N)
{
if(N==0)
return 1;
if(N%2)
return Pow(X*X,N/2)*X;
else
return Pow(X*X,N/2);
}
1.时间复杂度分析:
一般,log均指以2为底求对数。对于大O分析,直接考虑最坏情况。
显然,运行次数包括 N==0的O(1)部分以及奇偶判断后面的return递归(对半分)。
1.O(1)容易,先不理。
2.因为每次递归分解return中,当N为奇数时,有乘法次数最大,为2。 假设递归过程中,N均为奇数。(最坏情况)
又由于,对于N每次对半分; 则,对于自然数N有:一定存在N0=2^x,使得N < N0,其中x为自然数;
则,有对N0对半分,直到N=1,再继续1/2=0,次数为log(N0)+2(’2’为包括计算到了1,0的次数)。
同理,N对半分次数应该也是log(N),且N的对半分次数比N0小。 所以,有最多为2[log(N)]+4(此处[ ]为向上取整)
3.所以,有O(log(N))
2.Some More Note:
1.对于N为奇数递归return语句,可改为:
return Pow(X,N-1)*X
2.然而以下修改有误:
return Pow(Pow(X,2),N/2)
OR
return Pow(Pow(X,N/2),2)
因为,当N=2时,有死循环
3.存在第四种修改:
return Pow(X,N/2)*Pow(X,N/2);
可以运行,然而此处有两个Pow递归调用,不再是O(log(N)),而是以下分析:
对于return Pow(X,N/2)*Pow(X,N/2),每次都有2的次方增加的数列:(括号内为乘法次数)
(N);(0)
(N/2∗N/2);(20)
(N/4∗N/4),(N/4∗N/4);(21)
(N/8∗N/8),(N/8∗N/8),(N/8∗N/8),(N/8∗N/8);(22)
...
0(2(log(N)+2−2))
则运行次数为
如下图为y=n&y=log(n)大致趋势图: