Analyzing Time Complexity of Recursive Functions: powerA and powerB Functions, Study notes of Computer Science

The time complexity analysis of recursive functions through the use of recurrence relations. The document focuses on the powera and powerb functions, providing insights into the number of operations required to execute each function for a given input size. The analysis is based on the reduction in problem size and the number of arithmetic operations involved at each recursive call.

Typology: Study notes

Pre 2010

Uploaded on 11/08/2009

koofers-user-ih7
koofers-user-ih7 🇺🇸

10 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Recursion - II
pf3
pf4
pf5

Partial preview of the text

Download Analyzing Time Complexity of Recursive Functions: powerA and powerB Functions and more Study notes Computer Science in PDF only on Docsity!

Recursion - II

Time Complexity Analysis of Recursive functions using

Recurrence relations:

The time complexity of an algorithm gives an idea of the number of operations needed to solve it. While we shall discuss the time complexity issues in more detail later, in this section we work out the number of operations for the some of the recursive functions that we have developed so far. To do this we make use of recurrence relations. A recurrence relation , also known as a difference equation , is an equation which defines a sequence recursively: each term of the sequence is defined as a function of the preceding terms.

Let us look at the powerA function (exponentiation).

int powerA( int x, int n) { if (n==0) return 1; if (n==1) return x;

else return x * powerA( x , n–1 ); }

The problem size reduces from n to n – 1 at every stage, and at every stage two arithmetic operations are involved (one multiplication and one subtraction). Thus total number of operations needed to execute the function for any given n, can be expressed as sum of 2 operations and the total number of operations needed to execute the function for n-1. Also when n=1, it just needs one operation to execute the function

In other words T(n) can be expressed as sum of T(n-1) and two operations using the following recurrence relation :

T(n) = T(n – 1 ) + 2 T(1) = 1

We need to solve this to express T(n) in terms of n. The solution to the recurrence relation proceeds as follows. Given the relation T(n) = T(n – 1 ) + 2 ..(1)

we try to reduce the right hand side till we get to T(1) , whose solution is known to us. We do this in steps. First of all we note (1) will hold for any value of n. Let us rewrite (1) by replacing n by n-1 on both sides to yield

T(n – 1 ) = T(n – 2 ) + 2 …(2)

Complexity of the efficient recursive algorithm for exponentiation :

We now consider the powerB function.

int powerB( int x, int n) { if ( n==0) return 1; if(n==1) return x;

if (n is even) return powerB( x * x, n/2);

else return powerB( x * x, n/2 ) * x ; }

At every step the problem size reduces to half the size. When the power is an odd number, an additional multiplication is involved. To work out time complexity, let us consider the worst case, that is we assume that at every step an additional multiplication is needed. Thus total number of operations T(n) will reduce to number of operations for n/2, that is T(n/2) with three additional arithmetic operations (the odd power case). We are now in a position to write the recurrence relation for this algorithm as

T(n) = T(n/2) + 3 ..(1) T(1) = 1 ..(1)

To solve this recurrence relation, we note that T(n/2) can be expressed as

T(n/2) = T(n/4) + 3 ..(2)

Substituting for T(n/2) from (2) in relation (1) , we get

T(n) = T(n/4) + 3(2)

By repeated substitution process explained above, we can solve for T(n) as follows

T(n) = T(n/2) + 3 = [ T(n/4) + 3 ] + 3 = T(n/4) + 3(2) = [ T(n/8) + 3 ] + 3(2) = T(n/8) + 3(3)

Now we know that there is a relationship between 3 and 8, and we can rewrite the recurrence relation as

T(n) = T( n/ 2^3 ) + 3(3)

We can continue the process one step further, and rewrite the relation as

T(n) = T( n/ 2^4 ) + 3(4)

Now we can see a pattern running through the various relations and we can write the generalized relation as

T(n) = T( n/ 2k) + 3(k)

Since we know that T(1) = 1, we find a substitution such that the first term on the right hand side reduces to 1. The following choice will make this possible

2 k= n

We can get the value of k by taking log of both sides to base 2, which yields

k = log n

Now substituting this value in the above relation, we get

T(n) = 1 + 3 log n

Thus we can say that this algorithm runs in LOGARITHMIC TIME, and obviously is much more efficient than the previous algorithm.

Complexity of the recursive Binary search function Rbinary:

The time complexity of the algorithm can be obtained by noting that every time the function is called, the number of elements to be handled reduces to half the previous value. Assuming it takes one operation for each of the 3 IF statements, and 2 operations for computing mid, the total number of operations can be expressed through the recurrence relation

T(n) = T( n/2) + 5 with T(1) = 1

Note this relation is very similar to the one that we had for the efficient version of the exponentiation algorithm, and it can be shown that the complexity of this algorithm is also logarithmic.