Вы находитесь на странице: 1из 19

IT205: Data Structures Topic: Recursion

Anish Mathuria Faculty Block 1, 1105

A recursive definition is one which uses the word or concept being defined in the definition itself All recursive definitions have to have a non-recursive part
called the base case

If they didn't, there would be no way to terminate the recursive path

called infinite recursion

Recursive definitions
N!, for any positive integer N, is defined to be the product of all integers between 1 and N inclusive This definition can be expressed recursively as 1! = 1 N! = N * (N-1)! Eventually, the base case of 1! is reached

Consider the problem of computing the sum of all the numbers between 1 and any positive integer N Recursive solution
int sumOf(int N){ if (N < = 1)
return 1

return sumOf(N - 1) + N

Draw the recursive call stack

The Stack of activation records

Elegant Solutions?
Note that just because we can use recursion to solve a problem, doesn't mean we should For instance, we usually would not use recursion to solve the sum of 1 to N problem, because the iterative version is easier to understand However, for some problems, recursion provides an elegant solution

Take the array you would like to sort and divide it in half to create 2 unsorted subarrays Next, sort each of the 2 subarrays Finally, merge the 2 sorted subarrays into 1 sorted array


Although the merge step produces a sorted array, we have overlooked a very important step How did we sort the 2 halves before performing the merge step? We used merge sort!

By continually calling the merge sort algorithm, we eventually get a subarray of size 1 Since an array with only 1 element is clearly sorted, we can back out and merge 2 arrays of size 1


Input: An array A[0..N-1] storing N items Output: The array A sorted in ascending order Algorithm Merge_Sort(A, N): { if (N > 1) { h = N / 2, m = N h new(U[0..h-1]), new(V[0..m-1]) copy A[0] through A[h-1] to U[0] through U[h-1] copy A[h] through A[N-1] to V[0] through V[m-1] mergesort(U, h) mergesort(V, m) merge(h, m, U, V, A) } }

Input: Two sorted arrays U[0..h-1], V[0..m-1] Output: The array S[0..h+m-1] that merges U and V Algorithm Merge(h, m, U, V, S):
{ i :=0, j :=0, k :=0 while (i < h and j < m) { if (U[i] < V[j]) { S[k] := U[i], i := i + 1 } else { S[k] := V[j], j := j + 1 } k := k + 1 } if (i = h) copy V[j] through V[m-1] to S[k] through S[h+m-1] else copy U[i] through U[h-1] to S[k] through S[h+m-1] }

Time complexity (1)

Characteristic operation
the comparison of U[i] with V[j]

Input size
h and m, the number of items in each of the two input arrays

What is the worst case?

Time complexity (2)

Worst case
the first m 1 items in V are placed first in S, followed by all h items in U, at which time the loop is exited W(h, m) = h + m 1 = N 1 OR The first h 1 items in U are placed first in S, followed by all m items in V, at which time the loop is exited W(h, m) = h 1 + m = N 1

Time complexity (3)

Total number of comparisons
C(N) = C(h) + C(m) + N 1
The number of comparisons in the recursive call to mergesort with U as input The number of comparisons in the recursive call to mergesort with V as input The number of comparisons in the call to merge

Time complexity (4)

Assume N is a power of 2. Then h = m = N/2 If N = 1, no merging is done
C(1) = 0

If N > 1
C(N) = 2 C(N/2) + N 1

Time Complexity (5)

C(1) = 0 C(N) = 2 C(N/2) + N 1

for N > 1

We need to solve a recurrence relation! One way is to expand each recursive part by substitution
C(N/2) = 2C(N/4) + N/2 1

Substitute C(N/2) in formula

C(N) = 2 (2 C(N/4) + N/2 1) + N 1 = 4C(N/4) + 2N 3

Time Complexity (6)

Continue doing this
C(N) = 2 ( 2 ( 2 C(N/8) + N/4 1) + N/2 1) + N 1 = 23C(N/23) + 3N 7 C(N) = 2kC(N/2k) + kN (2k 1)

In termination case we have C(1) = 0

For having C(1) = C(N/2k), we should have k = log N

For k = log N
C(N) = 2logNC(N/2logN) + NlogN (N 1) C(N) = NC(1) + N logN (N 1) C(N) = N log N (N 1)