cs102 algorithms and programming ii1 recursion recursion is a technique that solves a problem by...

25
CS102 Algorithms and Programming II 1 Recursion Recursion is a technique that solves a problem by solving a smaller problem of the same type. •A recursive function is a function invoking itself, either directly or indirectly. • Recursion can be used as an alternative to iteration. • Recursion is an important and powerful tool in problem solving and programming. • Recursion is a programming technique that naturally implements the divide-and-conquer problem solving methodology.

Post on 19-Dec-2015

247 views

Category:

Documents


0 download

TRANSCRIPT

CS102 Algorithms and Programming II 1

Recursion

• Recursion is a technique that solves a problem by solving a smaller problem of the same type.

• A recursive function is a function invoking itself, either directly or indirectly.

• Recursion can be used as an alternative to iteration.

• Recursion is an important and powerful tool in problem solving

and programming.

• Recursion is a programming technique that naturally implements

the divide-and-conquer problem solving methodology.

CS102 Algorithms and Programming II 2

The Nature of Recursion

1. One or more simple cases of the problem (called the stopping cases or base case) have a simple non-recursive solution.

2. The other cases of the problem can be reduced (using recursion) to problems that are closer to stopping cases.

3. Eventually the problem can be reduced to stopping cases only, which are relatively easy to solve.

In general:if (stopping case) solve itelse reduce the problem using recursion

CS102 Algorithms and Programming II 3

Four Criteria of A Recursive Solution

1. A recursive function calls itself.– This action is what makes the solution recursive.

2. Each recursive call solves an identical, but smaller, problem.– A recursive function solves a problem by solving another problem that is identical in

nature but smaller in size.

3. A test for the base case enables the recursive calls to stop.– There must be a case of the problem (known as base case or stopping case) that is handled

differently from the other cases (without recursively calling itself.)– In the base case, the recursive calls stop and the problem is solved directly.

4. Eventually, one of the smaller problems must be the base case.– The manner in which the size of the problem diminishes ensures that the base case is

eventually is reached.

CS102 Algorithms and Programming II 4

Four Questions for Constructing Recursive Solutions

1. How can you define the problem in terms of a smaller problem of

the same type?

2. How does each recursive call diminish the size of the problem?

3. What instance of the problem can serve as the base case?

4. As the problem size diminishes, will you reach this base case?

CS102 Algorithms and Programming II 5

Factorial Function – Iterative Definition

n! = n * (n-1) * (n-2) * … * 2 * 1 for any integer n>0

0! = 1

Iterative Definition fval = 1;

for (i = n; i >= 1; i--)

fval = fval * i;

CS102 Algorithms and Programming II 6

Factorial Function - Recursive Definition

• To define n! recursively, n! must be defined in terms of the factorial of a smaller number.

• Observation (problem size is reduced):

n! = n * (n-1)! ( a recurrence relation)

• Base case: 0! = 1

• We can reach the base case, by subtracting 1 from n if n is a positive integer.

Recursive Definition:

n! = 1 if n = 0

n! = n * (n-1)! if n > 0

CS102 Algorithms and Programming II 7

Factorial Function - Recursive Definition in C++

static int fact(int n)// Computes the factorial of a nonnegative integer.

// Precondition: n must be greater than or equal to 0.

// Postcondition: Returns the factorial of n; n is unchanged.

{

if (n ==0)

return (1);

else

return (n * fact(n-1));

}

• This fact function satisfies the four criteria of a recursive solution.

CS102 Algorithms and Programming II 8

A Sequence of Computations of Factorial Function

CS102 Algorithms and Programming II 9

A Recursive void Function – Writing a String Backward

Problem: Write the given string of characters in reverse order.

Recursive Solution:

Base Case: Write the empty string backward.

Recursive Case: How can we write an n-character string backward, if we can write an (n-1)-character string backward?

• Strip away the last character, or strip away the first character

writeBackward(s:string)

if (the string s is empty)

Do nothing // base case

else {

Write the last character of s

writeBackward(s minus its last character)

}

CS102 Algorithms and Programming II 10

Writing a String Backward

static void writeBackward(String s, int size)

// Writes a character string backward.

// Precondition: The string s contains size characters, where size >= 0.

// Postcondition: s is written backward, but remains unchanged.

{

if (size > 0)

{ // write the last character

System.out.print(s.charAt(size-1));

// write the rest of the string backward

writeBackward(s, size-1); // Point A

} // end if

// size == 0 is the base case - do nothing

} // end writeBackward

CS102 Algorithms and Programming II 11

Vertical Numbers

• The static recursive method writeVertical takes one (nonnegative) int argument, and writes that int with the digits going down the screen one per line

– Note: Recursive methods need not be static

• This task may be broken down into the following two subtasks

– Simple case: If n<10, then write the number n to the screen

– Recursive Case: If n>=10, then do two subtasks:

• Output all the digits except the last digit

• Output the last digit

CS102 Algorithms and Programming II 12

Vertical Numbers

• Given the argument 1234, the output of the first subtask would be:123

• The output of the second part would be:4

• The decomposition of tasks into subtasks can be used to derive the method definition:– Subtask 1 is a smaller version of the original task, so it can be

implemented with a recursive call– Subtask 2 is just the simple case

CS102 Algorithms and Programming II 13

Vertical Numbers

public static void writeVertical(int n) {

if (n < 10) {

System.out.println(n);

}

else //n is two or more digits long:

{

writeVertical(n/10);

System.out.println(n%10);

}

}

CS102 Algorithms and Programming II 14

Binary Search

public static int search(int[] a, int first, int last, int key) { int result = 0; if (first > last) result = -1; else { int mid = (first + last)/2; if (key == a[mid]) result = mid; else if (key < a[mid]) result = search(a, first, mid - 1, key); else if (key > a[mid]) result = search(a, mid + 1, last, key); } return result;}

CS102 Algorithms and Programming II 15

The Towers of Hanoi

Problem:

• There are n disks and three poles: A(source), B(destination), C(spare)

• The disks are of different sizes and they had holes in the middle so that they can fit on the poles.

• The disks can be placed only top of disks larger than themselves.

• Initially, all the disks are on pole A.

• The disks can be moved one by one – At each move, only one disk can be moved from one pole to another without putting a

larger disk on the top of a smaller disk.

? Move all n disks from pole A (source) to pole B (destination)– Find all required disk movements.

CS102 Algorithms and Programming II 16

The Towers of Hanoi (cont.)

initial state

move n-1 disksfrom A to C

CS102 Algorithms and Programming II 17

The Towers of Hanoi (cont.)

move 1 diskfrom A to B

move n-1 disksfrom C to B

CS102 Algorithms and Programming II 18

The Towers of Hanoi – Recursive Solution

solveTowers(count, source, destination, spare)if (count is 1) move a disk directly from source to destinationelse { solveTowers(count-1, source, spare, destination) solveTowers(1, source, destination, spare) solveTowers(count-1, spare, destination, source)}

• This recursive solution to the Towers problem satisfies the four criteria of a recursive solution.

CS102 Algorithms and Programming II 19

The Order of Recursive Calls of solveTowers(3,A,B,C) – Recursion Tree

CS102 Algorithms and Programming II 20

The Solution for Three Disks

1. Move top disk from pole A to pole B

2. Move top disk from pole A to pole C solveTowers(2,A,C,B)

3. Move top disk from pole B to pole C

4. Move top disk from pole A to pole B

5. Move top disk from pole C to pole A

6. Move top disk from pole C to pole B solveTowers(2,C,B,A)

7. Move top disk from pole A to pole B

}

}

CS102 Algorithms and Programming II 21

The Towers of Hanoi

void solveTowers(int count, char source, char destination, char spare){ if (count == 1) {

System.out.println( "Move top disk from pole " +source+" to pole " +destination );

} else { solveTowers(count-1, source, spare, destination); // X solveTowers(1, source, destination, spare); // Y solveTowers(count-1, spare, destination, source); // Z } // end if} // end solveTowers

CS102 Algorithms and Programming II 22

Recursion and Efficiency

• Recursion is a powerful problem-solving technique that often produces very clean solutions to even most complex problems.

• Recursive solutions can be easier to understand and to describe than iterative solutions.

• But some recursive solutions are inefficient.– factorial, writeBackward functions are inefficient.

– We can have efficient iterative versions of these recursive solutions.

• We shouldn’t use a recursive solution if it is inefficient and we have a clear, efficient iterative solution.

Recursion is truly valuable when a problem has

no simple iterative solution.

CS102 Algorithms and Programming II 23

Comparison of Iteration and Recursion

• In general, an iterative version of a program will execute more efficiently in terms of time and space than a recursive version. – This is because the overhead involved in entering and exiting a function is avoided in

iterative version.

– The inherent inefficiency of some recursive algorithms.

• However a recursive solution can be sometimes the most natural and logical way of solving a problem.– Conflict: machine efficiency versus programmer efficiency.

• It is always true that a recursive solution can be replaced with an iterative solution using a stack.

• If a recursive solution is inefficient, we can convert that recursive solution to an efficient iterative solution.

CS102 Algorithms and Programming II 24

writeBackward

void writeBackward(String s, int size) { // Recursive version

if (size > 0) {

System.out.print(s.charAt(size-1));

writeBackward(s, size-1);

}

}

----------------------------------------------------------------------------------------------

void writeBackward(String s, int size) { // Iterative version.

while (size > 0) {

System.out.print(s.charAt(size-1));

--size;

}

}

CS102 Algorithms and Programming II 25

Iterative Binary Search

public static int search(int[] a, int lowEnd, int highEnd, int key) { int first = lowEnd; int last = highEnd; int mid; boolean found = false; int result = 0; while ( (first <= last) && !(found) ) { mid = (first + last)/2; if (key == a[mid]) { found = true; result = mid; } else if (key < a[mid]) last = mid - 1;

else if (key > a[mid]) first = mid + 1; } if (first > last) result = -1; return result;}