WITH C++ Prof. Amr Goneid AUC Part 12. Recursion Prof. amr - - PowerPoint PPT Presentation

with c
SMART_READER_LITE
LIVE PREVIEW

WITH C++ Prof. Amr Goneid AUC Part 12. Recursion Prof. amr - - PowerPoint PPT Presentation

CSCE 110 PROGRAMMING FUNDAMENTALS WITH C++ Prof. Amr Goneid AUC Part 12. Recursion Prof. amr Goneid, AUC 1 Recursion Prof. amr Goneid, AUC 2 Recursion Definition Examples from Math Functions Why Recursion Rules for


slide-1
SLIDE 1
  • Prof. amr Goneid, AUC

1

CSCE 110 PROGRAMMING FUNDAMENTALS

WITH C++

  • Prof. Amr Goneid

AUC Part 12. Recursion

slide-2
SLIDE 2
  • Prof. amr Goneid, AUC

2

Recursion

slide-3
SLIDE 3
  • Prof. amr Goneid, AUC

3

Recursion

 Definition  Examples from Math Functions  Why Recursion  Rules for Recursion  General Recursive Structures  Famous Methods  The Role of the Stack  Recursive Array processing using Exclude &

Conquer

 Recursive Array processing using Divide &

Conquer

 More Examples  Iterative VS Recursive Algorithms

slide-4
SLIDE 4
  • Prof. amr Goneid, AUC

4

  • 1. Definition

 recur

From the Latin, re- = back + currere = to run To happen again, especially at repeated intervals.

 Many problems can be solved recursively,

e.g. games of all types from simple ones like the Towers of Hanoi problem to complex

  • nes like chess.

 If a data structure may be defined recursively,

it may be processed by a recursive function!

slide-5
SLIDE 5
  • Prof. amr Goneid, AUC

5

Recursive Functions

 Has the the ability to call itself.  A finite number of recursive calls with different input

parameters in each call.

 Desired result is obtained from current action and the

contributions of previous actions (history).

 Terminal action is predefined (does not need

previous history).

 The termination condition (Base Case) is obviously

extremely important. If it is omitted, then the function will continue to call itself indefinitely.

slide-6
SLIDE 6
  • Prof. amr Goneid, AUC

6

How It Works

Base Case Big Problem (n) (General Case) Get Previous History Combine Problem Gets Smaller n-1 n-2

slide-7
SLIDE 7
  • Prof. amr Goneid, AUC

7

  • 2. Examples from Math Functions

 Sum of the first n integers

Sum(n) = 1+2+3+….+(n-1)+n // An Iterative Algorithm int sum (int n) { int i; int s = 0; for ( i = 1; i <= n; i++) s += i; return s; }

slide-8
SLIDE 8
  • Prof. amr Goneid, AUC

8

Recursive Sum Algorithm

The sum of the first n integers is defined as: // A Recursive Algorithm int sum (int n){ if ( n == 1) return 1; else return sum(n-1) + n; }

1 1 1

1 1 ( ) 1

n n i i

n i i n n

− = =

=     =   + >    

∑ ∑

slide-9
SLIDE 9
  • Prof. amr Goneid, AUC

9

When we call sum(n), e.g. int k = sum(3);

sum (2) ……. 2 + sum(1)

Recursive Sum Algorithm (How it works)

sum (3) ……. 3 + sum(2) sum(1) return 1 Base case 1 3 6 A general case

slide-10
SLIDE 10
  • Prof. amr Goneid, AUC

10

  • 3. Why Recursion

 When current result depends on

previous history.

 Some problems are easier to code

recursively.

 When processing a large data structure

that is composed of similar but smaller structures (e.g. trees).

slide-11
SLIDE 11
  • Prof. amr Goneid, AUC

11

  • 4. Rules for Recursion

 There must be a base case.  There is a general case other than the base

case.

 There is a path from a general case to the

base case.

 Successive recursive calls should take us

towards the base case. The problem should get smaller in that direction.

slide-12
SLIDE 12
  • Prof. amr Goneid, AUC

12

  • 5. General Recursive Structures

 Structure(1):

if (Base Case) {Terminal Action}; else {General Case Actions};

 Structure(2):

if (! Base Case) {General case Actions};

slide-13
SLIDE 13
  • Prof. amr Goneid, AUC

13

Examples from Math Functions

 Factorial of n = n! = 1*2*3…*n =

Hence Factorial(n) = 1 for n = 0 (base case) = n * Factorial(n-1) for n > 0

1 ! ( 1)! n n n n n =   =   − >  

1 n i

i

=

slide-14
SLIDE 14
  • Prof. amr Goneid, AUC

14

Examples

 An Iterative Factorial Function:

int factorial (int n) { int i , f ; f = 1; if ( n > 0 ) for (i = 1; i <= n; i++) f * = i ; return f ; }

slide-15
SLIDE 15
  • Prof. amr Goneid, AUC

15

 A Recursive Factorial Function:

int factorial (int n) { if (n <= 0) return 1; else return ( n * factorial (n-1)); } e.g. m = factorial(4);

Examples

slide-16
SLIDE 16

Factorial Tracing

  • Prof. amr Goneid, AUC

16

slide-17
SLIDE 17
  • Prof. amr Goneid, AUC

17

Example: Power Function

 A numeric value x raised to an integer power:

1

1

n n

n x x x n

=   =   >  

slide-18
SLIDE 18
  • Prof. amr Goneid, AUC

18

 A Recursive Function to return xn:

double power (double x, int n) { if (n == 0 ) return 1.0; else return ( x * power(x,n-1)); } e.g. y = power(x , 5);

Power Function

slide-19
SLIDE 19
  • Prof. amr Goneid, AUC

19

 A Recursive function to print elements of an array A from

index s through index e. Main call may be printlist(A,0,n-1):

void printlist (int A[ ], int s, int e) { if (s <= e ) { cout << A[s]; printlist (A, s+1, e); } }

Examples

slide-20
SLIDE 20
  • Prof. amr Goneid, AUC

20

  • 6. Famous Methods

 Exclude and Conquer

n 1 n-1 Base 1 1

slide-21
SLIDE 21
  • Prof. amr Goneid, AUC

21

Famous Methods

 Divide and Conquer

n n/2 n/2 Base n/4 n/4

slide-22
SLIDE 22
  • Prof. amr Goneid, AUC

22

  • 7. The Role of the Stack

 Each call to a module pushes a stack frame on the

  • stack. One stack frame has 3 items:

 Where the jump to the module came from.  The input parameters  The result (or output parameters).

Then it pops them out, returning results to the calling module.

3 Results 2 Input params 1 Where from

Push Pop

slide-23
SLIDE 23
  • Prof. amr Goneid, AUC

23

The Role of the Stack

 Example:

factorial(2) returns 2 factorial(1) * 2 = 2 factorial(0) * 1 = 1

1 Base Case

slide-24
SLIDE 24
  • Prof. amr Goneid, AUC

24

The Role of the Stack

1 n = 0

Addr3

? n = 1

Addr2

? n = 2

Addr1

? n = 2

Addr1

? n = 1

Addr2

?

n = 2

Addr1

1 n = 1

Addr2

? n = 2

Addr1

2 n = 2

Addr1

slide-25
SLIDE 25
  • Prof. amr Goneid, AUC

25

  • 8. Recursive Array processing using

Exclude & Conquer

 Recursive sum of array elements from location s

through location e. int array_sum (int A[ ], int s, int e) { if (s == e) return A[s]; else return (A[s] + array_sum (A, s+1, e)); }

slide-26
SLIDE 26
  • Prof. amr Goneid, AUC

26

Recursive Array processing using Exclude & Conquer

 Number of zero elements in an array from

location s through location e. int nzeros (int A[ ], int s, int e) { int k = (A[s] == 0? 1 : 0); if (s == e) return k; else return (k + nzeros (A, s+1, e)); }

slide-27
SLIDE 27
  • Prof. amr Goneid, AUC

27

Recursive Array processing using Exclude & Conquer

 Reversing an Array

void ReverseArray (int A[ ], int s, int e) { if (s < e) { swap (A[s] , A[e]); ReverseArray ( A , s+1, e-1);} }

slide-28
SLIDE 28
  • Prof. amr Goneid, AUC

28

Recursive Sequential Search

 Recursive Sequential Search of x in array A from

location s through location e. int LinSearch (int A[ ], int x, int s, int e) { if (x == A[s]) return s; else if (s == e) return -1; else return LinSearch (A,x,s+1,e); }

slide-29
SLIDE 29
  • Prof. amr Goneid, AUC

29

Recursive Selection Sort

 Recursive Selectsort of array A from location s through

location e. Invoke e.g. as SelectSort(A , 1 , n)

void SelectSort (int A[ ], int s, int e) { int m; if (s < e) { m = index_of_min(A,s,e); swap(A[m] , A[s]); SelectSort (A , s+1 , e); } }

slide-30
SLIDE 30
  • Prof. amr Goneid, AUC

30

  • 9. Recursive Array Processing using

Divide & Conquer

 Maximum value in an array from location s

through location e.

 Assume we have a function that returns the

greater of two values (a,b) int max2 (int a, int b) { return ((a > b)? a : b); }

slide-31
SLIDE 31
  • Prof. amr Goneid, AUC

31

Maximum in an Array

int maximum (int a[ ], int s, int e) { // Base Case if (s == e) return a[s]; else // General Case { int m = (s + e)/2; // Divide in the middle int maxL = maximum (a , s , m); // Conquer left half int maxR = maximum (a , m+1 , e); // Conquer right return max2 ( maxL , maxR); // Combine } }

slide-32
SLIDE 32
  • Prof. amr Goneid, AUC

32

Recursive Binary Search

 Search for an element x in an array A of

elements sorted in ascending order. The function Bsearch (A,x,s,e) returns the index of x if found and -1 otherwise.

s e mid A

slide-33
SLIDE 33
  • Prof. amr Goneid, AUC

33

Recursive Algorithm

int Bsearch (int A[ ], int x, int s, int e) { int mid; // Base case: No elements left, search failed if (s > e) return -1; else { // General case mid = (s+e) / 2; // Divide in the middle if (x == A[mid]) return mid; // Success at mid else (if x > A[mid]) // Conquer right return Bsearch(A,x,mid+1,e); else // Conquer left return Bsearch(A,x,s,mid-1); } }

slide-34
SLIDE 34
  • Prof. amr Goneid, AUC

34

  • 10. More Examples

The Towers of Hanoi

In the Towers of Hanoi game, there are 3 pegs (A , B , C) and N disks with varying sizes that can be stacked

  • n a peg. The objective is to move all the disks from peg

(A) to peg (C), probably by using the auxiliary peg (B). At any moment, no larger peg can be placed on top of a smaller one.

slide-35
SLIDE 35
  • Prof. amr Goneid, AUC

35

The Towers of Hanoi

For example: To move one disk from A to C: Move disk1 from A to C To move two disks (top is 1, bottom is 2): Move 1 from A to B Move 2 from A to C Move 1 from B to C To move N disks from A to C and we already know how to move N-1 disks from any one peg to another: Move the top N-1 disks by a series of legal moves from A to B using C Move Disk N from A to C directly Move N-1 disks from B to C using A

slide-36
SLIDE 36
  • Prof. amr Goneid, AUC

36

Algorithm

Obviously, this is a recursive problem that can be solved by the following recursive algorithm: Towers (N, A , C , B) { if N = 1 move disk 1 from A to C directly else { Towers ( N-1 , A , B , C) Move disk N from A to C directly Towers ( N-1 , B , C , A) } }

slide-37
SLIDE 37
  • Prof. amr Goneid, AUC

37

Animation

An animation is available at:

http://www.cosc.canterbury.ac.nz/people/m ukundan/dsal/ToHdb.html

slide-38
SLIDE 38
  • Prof. Amr Goneid, AUC

38

Euclide’s Algorithm for the GCD (Recursive Version)

//Computes gcd(m, n) by Euclid’s algorithm //Input: Two nonnegative, not-both-zero integers m and n //Output: Greatest common divisor of m and n

function gcd(m, n) if n = 0 return m else return gcd (n, m mod n)

"The Euclidean algorithm is the granddaddy of all algorithms, because it is the oldest nontrivial algorithm that has survived to the present day”. Donald Knuth, The Art of Computer Programming, Vol. 2

slide-39
SLIDE 39
  • Prof. Amr Goneid, AUC

39

Non-Recursive Algorithm

ALGORITHM Euclid (m, n) //Computes gcd(m, n) by Euclid’s algorithm //Input: Two nonnegative, not-both-zero integers m and n //Output: Greatest common divisor of m and n

while n != 0 do r ←m mod n m←n n←r return m

slide-40
SLIDE 40
  • Prof. Amr Goneid, AUC

40

Recursive Power Function (Divide & Conquer)

A power function can be defined as follows:

2 /2 2 /2

1 1 ( ) 1, ( ) 1,

n n n

n x n x x x n n odd x n n even =     =   =   >     >  

slide-41
SLIDE 41
  • Prof. Amr Goneid, AUC

41

Recursive Power Function

The recursive function would be: double pow (double x, int n) { if (n == 0) return 1.0; else if (n == 1) return x; else if (n%2) return pow (x*x, n/2) * x; else return pow (x*x, n/2);

slide-42
SLIDE 42
  • Prof. Amr Goneid, AUC

42

Binary Tree Traversal

A Binary Tree is a special data structure where a node has a maximum

  • f two children

The nodes in the BST can be implemented as a linked structure:

left

element right

16 45 32 40

32 16 45 40

t

slide-43
SLIDE 43
  • Prof. Amr Goneid, AUC

43

Binary Tree Traversal

Algorithm: Pre-order Traversal (Visit parent before children) void PreOrder ( tree T) { if ( T != NULL) { Visit (T); PreOrder (T->left); PreOrder (T->right); } }

The resulting visit order = {a} {b , d , e} {c , f }

b c a d e f

1 2 3 5 6 4

T

slide-44
SLIDE 44
  • Prof. Amr Goneid, AUC

44

Fractal Star

Example: a Fractal Algorithm

The following function draws recursive squares (called a fractal star). The drawing primitive is Box (x , y , n) which draws a square of side (n) pixels centered at (x,y) : void STAR( int x, int y, int n) { if (n > 1){ STAR(x-n , y+n , n/2); STAR(x+n , y+n , n/2); STAR(x-n , y-n , n/2); STAR(x+n , y-n , n/2); Box(x , y , n); } }

slide-45
SLIDE 45
  • Prof. Amr Goneid, AUC

45

  • 11. Iterative VS Recursive Algorithms

 Recursive Algorithms can be more elegant in

programming and easier to understand.

 They will cost about 5% more time than an

equivalent iterative algorithm.

BUT, Sometimes a recursive

algorithm can be a Disaster

slide-46
SLIDE 46
  • Prof. Amr Goneid, AUC

46

Example: Fibonacci Numbers

 Fibonacci numbers represent the sequence:

0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,...

 Introduced by Leonardo Fibonacci (1202)  Can be computed by the recurrence

relation:

1 n = 0 or 1 ( ) ( 1) ( 2) n > 1 F n F n F n   =   − + −  

slide-47
SLIDE 47
  • Prof. Amr Goneid, AUC

47

Fibonacci Numbers

Fibonacci numbers are closely related to the Golden Ratio φ since:

ϕ ψ ϕ ψ ϕ − = = + = − = 1 .., 6180339887 . 1 2 5 1 where 5

n n n

F

slide-48
SLIDE 48
  • Prof. Amr Goneid, AUC

48

The Golden Ratio

slide-49
SLIDE 49
  • Prof. Amr Goneid, AUC

49

In Nature

slide-50
SLIDE 50
  • Prof. Amr Goneid, AUC

50

In Nature

slide-51
SLIDE 51
  • Prof. Amr Goneid, AUC

51

In Architecture & Design

slide-52
SLIDE 52
  • Prof. Amr Goneid, AUC

52

In ART

slide-53
SLIDE 53
  • Prof. Amr Goneid, AUC

53

In Art

slide-54
SLIDE 54
  • Prof. Amr Goneid, AUC

54

Recursive Algorithm

Divide & Conquer Algorithm implemented as a recursive function: int Fib(int n) { if (n < 2) return 1; else return Fib(n-2) + Fib(n-1); }

slide-55
SLIDE 55
  • Prof. Amr Goneid, AUC

55

Recursive Algorithm

Analysis

Tracing for n = 5

5 3 4 1 2 2 3 1 2 1 1 1 n 1 2 3 4 5 Calls 1 3 5 9 15

slide-56
SLIDE 56
  • Prof. Amr Goneid, AUC

56

Recursive Algorithm

 This solution is an example of Overlapping Subproblems.  It means that any recursive algorithm solving the problem

should solve the same subproblems over and over, rather than generating new subproblems.

 The number of calls is ~ ϕn  The cost is very high because we keep computing the same

instance over and over again.

 For example:

It will take about 6369 Years to compute Fib(100) using a computer with 4 Gega Operations/sec. !!

.

slide-57
SLIDE 57
  • Prof. amr Goneid, AUC

57

 Using an array A of integers:

A[0] = A[1] = 1; if (n >= 2) for (i = 2; i <= n; i++) A[i] = A[i-1] + A[i-2]; return A[n]; For n >=2 , the cost is only (n-1) additions. n = 100 will cost only 99 array additions

Dynamic Programming Algorithm