Download presentation
Presentation is loading. Please wait.
Published byOwen Barnett Modified over 8 years ago
1
Maitrayee Mukerji
2
Factorial For any positive integer n, its factorial is n! is: n! = 1 * 2 * 3 * 4* ….* (n-1) * n 0! = 1 1 ! = 1 2! = 1 * 2 = 2 5! = 1 * 2 * 3 * 4 * 5 = 120 10! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 = 3628800
3
Contd… int Factorial (int n) {fac = 1; for (i=2; i <= n; i++) fac = fac * n; return (fac) } main () { cin >> n; int nfac = Factorial (n); cout << nfac; return 0; } => Iterative Implementation, loop is used to accomplish the task
4
Example..contd. Another way of looking at factorial is: 5! = 5 * 4 * 3 * 2 * 1 = 5 * 4! = 5 * 4 * 3! = 5 * 4 * 3 * 2! = 5 * 4 * 3 * 2 * 1! = 5 * 4 * 3 * 2 * 1 In general, factorial of any integer n is: n! = n * (n-1)!
5
Factorial: Recursive Definition Base Case Recursive Case 1 if n = 0 n! = n * (n-1) ! if n> 0
6
Example – Factorial Recursive int factorial (int n) {if n == 0 then return (1); else return ( n * factorial (n-1)); }
7
Recursion – Example void Print(int k) {cout << k; Print(k + 1); } main {Print (2); }
8
void Print2(int k) { if (k < 0) return; cout << k; Print2(k + 1); } main { Print2 (2); }
9
Print(int k) { if (k == 0) { return; } cout<< (k); Print(k - 1); } main {Print (2); }
10
Recursion Recursion : when a function refers to itself in its own definition When one function calls itself rather than some other functions, it is said to be a recursive function The method in which a problem is solved by reducing it to smaller cases of the same problem Provides an elegant and powerful alternative for performing repetitive tasks
11
Types of Recursion Linear Recursion Binary Recursion Non-linear Recursion Mutual Recursion
12
Linear Recursion Recursive algorithm in which only one internal recursive call is made within the body of the function. General Framework Function linear () {if “termination condition satisfied” then return some value else {perform some action make a further recursive call to linear() } Examples: Factorial, Greatest Common Divisor
13
Example: Reversing an Array Input: An array A and nonnegative integer indices i and j Output: The reversal of the elements in A starting at index i and ending at j ReverseArray(A, i, j) {if i < j then {Swap A[i] and A[ j] ReverseArray(A, i+1, j−1) return } } main() {ReverseArray(A, 0,n-1) }
14
Example: GCD The greatest common divisor (gcd) of two or more integers (at least one of which is not zero), is the largest positive integer that divides the numbers without a remainder Divisors (8) = 1, 2, 4, 8 Divisors (12) = 1, 2, 3, 4, 6, 12 Common Divisors = 1,2, 4 GCD (8,12) = 4
15
GCD…Euclid Algorithm Suppose d is a common divisor of two integers X and Y where X>Y Then X = q 1 d and Y = q 2 d => X-Y = q 1 d - q 2 d = (q 1 - q 2 )d = q 3 d => d is also a divisor of X-Y Euclid Algorithm GCD (X,Y) == GCD(Y, X-Y) E.g. GCD (20,12) = GCD (12,8) == GCD (8,4) == GCD (4,4) = 4
16
GCD..Euclid Algorithm Assuming two positive integers X, Y and X> Y int GCD (X,Y) {while (Y!=0) {r = X mod Y X = Y Y = r } return X } => Iterative Algorithm GCD (20,12) XYr 20128 84 840 404 GCD (20,12) = 4
17
GCD … Recursive Algorithm int gcd(int X, int Y) {if Y== 0 then gcd = X; else gcd = gcd (Y, X mod Y); return gcd; }
18
Recursive Trace/Depth of Recursion GCD (24, 18) GCD (18, 6) GCD (6,0) 6 6 6
19
Recursive Trace/Depth of Recursion Factorial (4) Factorial (3) Factorial (2) Factorial (1) Factorial (0) 1 1 2 6 24 Depth of Recursion = 5
20
Call Stack This is how method calls (recursive and non-recursive) really work: At runtime, a stack of activation records (ARs) is maintained: one AR for each active method, where "active" means: has been called, has not yet returned. This stack is also referred to as the call stack. Each AR includes space for: the method's parameters, the method's local variables, the return address -- where (in the code) to start executing after the method returns. When a method is called, its AR is pushed onto the stack. The return address in that AR is the place in the code just after the call. When a method is about to return, its AR is popped from the stack, and control is transferred to the place in the code referred to by the return address.
21
Example: non-recursive function 1. void printChar (char c) 2. { cout << c; 3. } 4. void main (... ) 5. { char ch = 'a'; 6. printChar(ch); 7. ch = 'b'; 8. printChar(ch); 9. } Main ‘s AR ch = “a” Return add: System Call Stack PrintChar ‘s AR ch = “a” Return add: Line 7 PrintChar ‘s AR ch = “b” Return add: Line 9 Main ‘s AR ch = “b” Return add: System
22
Example: recursive function 1.void printInt( int k ) 2.{ if (k <= 0) return; 3. cout<< k ; 4. printInt( k - 1 ); 5. } 6. void main(... ) 7.{ printInt( 2 ); 8.} PrintInt ‘s AR k = “2” Return add: Line 8 Main ‘s AR Return add: System 2 PrintInt ‘s AR k = “1” Return add: Line 5 1 PrintInt ‘s AR k = “0” Return add: Line 5
23
exercise 1. void printInt(int k) { 2. if (k <= 0) return; 3. printInt (k – 1); 4. cout << k; 5. } 6. void main(... ) 7. { printInt( 2 ); 8.}
24
Drawbacks of Linear Recursion Greater risk of incurring large depth of recursion Each recursive call requires the saving of an additional set of parameter, local variables and links Thus recursive algorithms can be much more expensive in use of memory than simple iterative solutions This overhead can make linearly recursive algorithms slower than more concise iterative versions
25
Binary Recursion An algorithm that makes two internal recursive calls to itself A problem is solved by first breaking it down into two smaller problems that are each in turn solved by being broken into two still smaller problems, and so on recursively Wide applications and importance Recursively defined data structures eg. Fibonacci Series, Binary Tree Traversal, Binary Search, Quicksort
26
Binary Recursion function binary () { if “termination condition” met then perform some action(s) and/or return some value else { (1) perform some actions (2) make a recursive call to binary() that solves one of the two smaller problems (3)make another recursive call to binary() to solve the other small problem }
27
Binary Recursion - Example Fibonacci Sequence of n (>= 0) numbers is = 0, 1, 1, 2, 3, 5, 8, 13……. Each term (other than the first two) is the sum of its immediate predecessor void fib (int n) { int a=0; b = 1; i =2; while (i<= n) do {c=a+b; a = b; b = c; i++ } } => Iterative Algorithm
28
Fibonacci …. Recursive Recursive Definition fib (1) = 0 fib (2) =1 fib (n) = fib(n-1) + fib(n-2) if n> 2
29
Contd. int binfib(int n) { if (n == 1) return 0 else if (n < 3) return 1 else return (binfib(n-1) + binfib(n-2) ) } main() {cin >> n; for (int i=1; i<= n; i++) {cout << binfib(i) << endl; }
30
Fibonacci …. Recursive fib (5) fib (4) fib (3) fib (2)fib (1) fib (2) fib (3) fib (2)fib (1)
31
Fibonacci …. Linear Recursive Input: A nonnegative integer k Output: Pair of Fibonacci numbers (Fk,Fk−1) Algorithm LFib(k) {if k ≤ 1 then return (k,0) else { (i, j) ← LFib(k−1) return (i + j, i) } }
32
Fibonacci …. Linear Recursive fib (7) fib (6) fib (5) fib (4) fib (3) fib (2) fib (1) (1, 0) (1, 1) (2,1) (3,2) (5,3) (8,5)
33
Non-linear Recursion An algorithm or function uses a number of internal recursive calls Multiple internal recursive calls are usually generated by placing a single recursive call within a loop
34
Non-linear Recursion General Framework Function nonlinear() {for j = k to n {perform some actions if “termination condition not met” then make a further recursive call to nonlinear() else perform some actions }
35
Quick Sort Fast sorting algorithm, using divide and conquer strategy Original Set of Unsorted Data Pivot All elements<= PivotAll elements > Pivot Pivot <= PivotL>PivotL<= PivotR> PivotR Pivot PivotLPivotR
36
Recursive QuickSort Choose a pivot value: first value, or the middle value, it can be any value, which is in range of sorted values, even if it doesn't present in the array. Partition. Rearrange elements in such a way, that all elements which are lesser than the pivot go to the left part of the array and all elements greater than the pivot, go to the right part of the array. Values equal to the pivot can stay in any part of the array. Notice, that array may be divided in non-equal parts. Sort both parts. Apply quicksort algorithm recursively to the left and the right parts.
37
Contd… QUICKSORT(A,p,r) { if p < r then {q = PARTITION(A,p,r) QUICKSORT(A,p,q) QUICKSORT(A,q + 1,r) }
38
Partitioning PARTITION(A,p,r) { x = A[p] i = p – 1 j = r + 1 while A[j] >= x j = j – 1 while A[i] < x i = i + 1 if i < j then swap A[i] A[j] return j } * This algorithm needs to be refined for handling all possible inputs.
39
Mutual Recursion A function calls itself indirectly via another function that calls its indirectly via the first function. Functions are interlocked together function mutual() {…..call another()….} function another() {…..call mutual()….}
40
Summary Using recursion can often be a useful tool for designing algorithms that have elegant, short definitions. But this usefulness does come at a modest cost. When we use a recursive algorithm to solve a problem, we have to use some of the memory locations in our computer to keep track of the state of each active recursive call. When computer memory is at a premium, then it is useful in some cases to be able to derive non-recursive algorithms from recursive ones.
41
References Dromey (1982), Chapter 8 on Recursive Algorithms Goodrich et.al. (2011) Chapter 3 Other Links http://pages.cs.wisc.edu/~skrentny/cs367- common/readings/Recursion/index.html Fibonacci Series: http://www.ics.uci.edu/~eppstein/161/960109.html Quick Sort : http://staff.ustc.edu.cn/~csli/graduate/algorithms/book6/ch ap08.htm Demo of Sorting Algorithms http://www.sorting-algorithms.com/
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.