recursion chapter 12. 2 12.1 nature of recursion t problems that lend themselves to a recursive...

Post on 28-Dec-2015

221 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Recursion

Chapter 12

2

12.1 Nature of Recursion

Problems that lend themselves to a recursive solution have the following characteristics:– One or more simple case of the problem have a

straightforward, non-recursive solution– Otherwise, use reduced cases of the problem that

are closer to a stopping case– Eventually the problem can be reduced to

stopping cases only. Easy to solve

3

Nature of Recursion

Splitting a problem into smaller problems

Size nProblem

Size n-1Problem

Size n-2Problem

Size 1problem

Size 1problem

Size 1problem

4

Power by Multiplication

Raise 6 to the power of 3– Raise 6 to the power of 22– Multiply the result by 6

Raise 6 to the power of 2– Raise 6 to the power of 1– Multiply the result by 6

Multiplying 6 * 6 * 6

5

Power.cpp

// FILE: Power.cpp

// RECURSIVE POWER FUNCTION

// Raises its first argument to the power

// indicated by its second argument.

// Pre: m and n are defined and > 0.

// Post:Returns m raised to power n.

int power (int m, int n)

{

if (n <= 1)

return m;

else

return m + power (m, n - 1);

}

6

12.2 Tracing Recursive Functions

Hand tracing we see how algorithm works Very useful in recursion Previous Multiply example trace “Activation Frame” corresponds to a

function call Darker shading shows the depth of

recursion

7

Trace of Power

8

Recursive Function with No Return Value

If statement with some stopping condition– n <= 1;

When TRUE stopping case is reached– recursive step is finished– falls back to previous calls (if any)– trace of reverse

ReverseTest.cpp

9

ReverseTest.cpp

#include <iostream>

using namespace std;

void reverse();

int main ()

{

reverse();

cout << endl;

return 0;

}

10

ReverseTest.cpp

void reverse()

{

char next;

cout << "Next character or * to stop: ";

cin >> next;

if (next != ‘*’)

{

reverse();

cout << next;

}

}

11

Reverse Trace

12

Argument and Local Variable Stacks

How does C++ keep track of n and next ? Uses a data structure called a stack Think of a stack of trays in a cafeteria Each time a function is called it is pushed onto

the stack Only top values are used when needed

(popping) Example of calls to reverse

13

Recursive String

After 1st call to reversen next

3 ? top– c is read into next just prior to 2nd call

n next

3 c top

14

Recursive String

After 2nd call to reversen next

2 ? top

3 c– letter a is read into next just prior to 3rd call

n next

2 a top

3 c

15

Recursive String

After 3rd call to reverse

n next

1 ? top

2 a

3 c– letter t is read into next printed due to stop case

n next

1 t top

2 a

3 c

16

Recursive String

After 1st returnn next

2 a top

3 c After 2nd return

n next

3 c After 3rd return (final)

? ?

17

12.3 Recursive Mathematical Functions

Many mathematical functions are defined recursively– factorial n! of a number– 0! = 1– n! = n * *n-1)! for n > 0– So 4! = 4 * 3 * 2 * 1 or 24

Look at a block of recursive math function example source code files

18

Factorial.cpp

// FILE: Factorial.cpp

// RECURSIVE FACTORIAL FUNCTION

// COMPUTES N!

int factorial (int n)

{

if (n <= 0)

return 1;

else

return n * factorial (n-1);

}

19

Factorial Trace

20

FactorialI.cpp

// FILE: FactorialI.cpp

// ITERATIVE FACTORIAL FUNCTION

// COMPUTES N!

int factorialI (int n)

{

int factorial;

factorial = 1;

for (int i = 2; i <= n; i++)

factorial *= i;

return factorial;

}

21

Fibonacci.cpp

// FILE: Fibonacci.cpp

// RECURSIVE FIBONACCI NUMBER FUNCTION

int fibonacci (int n)

// Pre: n is defined and n > 0.

// Post: None

// Returns: The nth Fibonacci number.

{

if (n <= 2)

return 1;

else

return fibonacci (n - 2) + fibonacci

(n - 1);

}

22

GCDTest.cpp

// FILE: gcdTest.cpp

// Program and recursive function to find

// greatest common divisor

#include <iostream>

using namespace std;

// Function prototype

int gcd(int, int);

23

GCDTest.cpp

int main()

{

int m, n; // the two input items

cout << "Enter two positive integers: ";

cin >> m >> n;

cout << endl;

cout << "Their greatest common divisor is " <<

gcd(m, n) << endl;

return 0;

}

24

GCDTest.cpp

// Finds the greatest common divisor of two

// integers

// Pre: m and n are defined and both are > 0.

// Post: None

// Returns: The greatest common divisor of m and

// n.

int gcd(int m, int n)

{

if (m < n)

return gcd(n, m);

25

GCDTest.cpp

else if (m % n == 0)

return n;

else

return gcd(n, m % n); // recursive step

}

26

GCDTest.cpp

Program Output

Enter two positive integers separated by a space: 24 84

Their greatest common divisor is 12

27

12.4 Recursive Functions with Array Arguments

// File: findSumTest.cpp

// Program and recursive function to sum an

// array's elements

#include <iostream>

using namespace std;

// Function prototype

int findSum(int[], int);

int binSearch(int[], int, int, int);

28

FindSumTest.cpp

int main()

{

const int SIZE = 10;

int x[SIZE];

int sum1;

int sum2;

// Fill array x

for (int i = 0; i < SIZE; i++)

x[i] = i + 1;

29

FindSumTest.cpp

// Calulate sum two ways

sum1 = findSum(x, SIZE);

sum2 = (SIZE * (SIZE + 1)) / 2;

cout << "Recursive sum is " << sum1 << endl;

cout << "Calculated sum is " << sum2 << endl;

cout << binSearch(x, 10, 10, SIZE-1) << endl;

return 0;

}

30

FindSumTest.cpp

// Finds the sum of integers in an n-element

// array

int findSum(int x[], int n)

{

if (n == 1)

return x[0];

else

return x[n-1] + findSum(x, n-1);

}

31

FindSumTest.cpp

// Searches for target in elements first through

// last of array

// Precondition : The elements of table are

// sorted & first and last are defined.

// Postcondition: If target is in the array,

// return its position; otherwise, returns -1.

int binSearch (int table[], int target,

int first, int last)

{

int middle;

32

FindSumTest.cpp

middle = (first + last) / 2;

if (first > last)

return -1;

else if (target == table[middle])

return middle;

else if (target < table[middle])

return binSearch(table, target, first,

middle-1);

else

return binSearch(table, target, middle+1,

last);

}

33

12.5 Problem Solving with Recursion

Case Study: The Towers of Hanoi Problem Statement

– Solve the Towers of Hanoi problem for n disks, where n is the number of disks to be moved from tower A to tower c

Problem Analysis– Solution is a printed list of each disk move.

Recursive function that can be used to move any number of disks from one tower to the other tower.

34

Towers of Hanoi

Program Design– If n is 1

• move disk 1 from fromTower to toTower

– else• move n-1 disks from fromTower to aux tower using

the toTower

• move disk n from the fromTower to the toTower

• move n-1 disks from aux tower to the toTower using fromTower

35

Towers of Hanoi

Program Implementation– Towers.cpp

Program Verification & Test– towers (‘A’, ’C’, ‘B’, 3);

Towers trace

36

Tower.cpp

// File: tower.cpp

// Recursive tower of hanoi function

#include <iostream>

using namespace std;

void tower(char, char, char, int);

int main()

{

int numDisks; // input - number of disks

37

Tower.cpp

cout << "How many disks: ";

cin >> numDisks;

tower('A', 'C', 'B', numDisks);

return 0;

}

// Recursive function to "move" n disks from

// fromTower to toTower using auxTower

// Pre: The fromTower, toTower, auxTower, and

// n are defined.

// Post: Displays the required moves.

38

Tower.cpp

void tower (char fromTower, char toTower,

char auxTower, int n)

{

if (n == 1)

cout << "Move disk 1 from tower " <<

fromTower << " to tower " << toTower <<

endl;

else

{

39

Tower.cpp

tower(fromTower, auxTower, toTower, n-1);

cout << "Move disk " << n <<

" from tower "<< fromTower <<

" to tower " << toTower << endl;

tower(auxTower, toTower, fromTower, n-1);

}

} // end tower

40

Towers Trace

41

TowerTest.cpp

Program Output

Move disk 1 from tower A to tower C

Move disk 2 from tower A to tower B

Move disk 1 from tower C to tower B

Move disk 3 from tower A to tower C

Move disk 1 from tower B to tower A

Move disk 2 from tower B to tower C

Move disk 1 from tower A to tower C

42

12.6 Common Programming Errors

Stopping conditions Missing return statements Optimizations

– recursion of arrays use large amounts of memory

– use care when tracing your solutions

top related