How can I calculate the time complexity of a recursive algorithm?
int pow1(int x,int n) {
if(n==0){
return 1;
}
else{
return x * pow1(x, n-1);
}
}
int pow2(int x,int n) {
if(n==0){
return 1;
}
else if(n&1){
int p = pow2(x, (n-1)/2)
return x * p * p;
}
else {
int p = pow2(x, n/2)
return p * p;
}
}
Analyzing recursive functions (or even evaluating them) is a nontrivial task. A (in my opinion) good introduction can be found in Don Knuths Concrete Mathematics.
However, let’s analyse these examples now:
We define a function that gives us the time needed by a function. Let’s say that
t(n)denotes the time needed bypow(x,n), i.e. a function ofn.Then we can conclude, that
t(0)=c, because if we callpow(x,0), we have to check whether (n==0), and then return 1, which can be done in constant time (hence the constantc).Now we consider the other case:
n>0. Here we obtaint(n) = d + t(n-1). That’s because we have again to checkn==1, computepow(x, n-1, hence (t(n-1)), and multiply the result byx. Checking and multiplying can be done in constant time (constantd), the recursive calculation ofpowneedst(n-1).Now we can “expand” the term
t(n):So, how long does it take until we reach
t(1)? Since we start att(n)and we subtract 1 in each step, it takesn-1steps to reacht(n-(n-1)) = t(1). That, on the other hands, means, that we getn-1times the constantd, andt(1)is evaluated toc.So we obtain:
So we get that
t(n)=(n-1) * d + cwhich is element of O(n).pow2can be done using Masters theorem. Since we can assume that time functions for algorithms are monotonically increasing. So now we have the timet(n)needed for the computation ofpow2(x,n):for
n>0we getThe above can be “simplified” to:
So we obtain
t(n) <= t(n/2) + d, which can be solved using the masters theorem tot(n) = O(log n)(see section Application to Popular Algorithms in the wikipedia link, example “Binary Search”).