• No results found

Lecture-6-recursion--2011-1.pdf

N/A
N/A
Protected

Academic year: 2020

Share "Lecture-6-recursion--2011-1.pdf"

Copied!
36
0
0

Loading.... (view fulltext now)

Full text

(1)

What is Recursion?

The word recursive means

: “having the characteristic of coming up again, or repeating.”

• You may have seen a set of gaily-painted Russian dolls that fit i id th

inside one another.

• Inside the first doll is a smaller doll, inside of which is an even smaller doll, inside of which is yet a smaller doll, and so on. A recursive algorithm is like such a set of Russian dolls

• A recursive algorithm is like such a set of Russian dolls.

• It reproduces itself with smaller and smaller versions of itself until a version is reached that can no longer be subdivided—that is, until the smallest doll is reached

the smallest doll is reached.

• The recursive algorithm is implemented by using a method that makes recursive calls to itself; analogous to taking the dolls apart one by one.

(2)

What is Recursion?

What is Recursion?

• It is a problem-solving process

B k bl i id i l b ll bl

• Breaks a problem into identical but smaller problems • Eventually you reach a smallest problem

– Answer is obvious or trivial

• Using that solution enables you to solve the previous problems • Using that solution enables you to solve the previous problems

– Eventually the original problem is solved

Recursive call: A method call in which the method being called is the same as the one making the call

Direct recursion: Recursion in which a method directly calls itself • Indirect recursion: Recursion in which a chain of two or more

method calls returns to the method that originated the chain (Indirect recursion occurs when method A calls method B and method B

(3)

Java and recursion

Java and recursion

• In Java, any method can invoke another method.

y

A method can even invoke itself!

• When a method invokes itself, it is making a

recursive call

recursive call

• Recursion is a powerful programming technique.

However, you must be careful when using

i

R

i

l ti

b l

recursion. Recursive solutions can be less

efficient than iterative solutions to the same

problem.

(4)

A Classic Example of Recursion

A Classic Example of Recursion

n

n

! (read “

! (read

n

n

factorial”) is used to calculate

factorial ) is used to calculate

the number of permutations of

n

elements.

• One mathematical description of

n

! is

(5)

A Classic Example of Recursion

A Classic Example of Recursion

• Consider the case of 4!. Because

Consider the case of 4!. Because

n

n

> 0, we use the

0, we use the

second part of the definition:

• 4! = 4 * 3 * 2 * 1 = 24

W

l

!

ith

t

i

th th

d t

• We can also express

n

! without using the three dots:

• This is a recursive definition because we express the

f

t i l f

ti

i t

f it

lf

(6)

A Classic Example of Recursion

A Classic Example of Recursion

• Let’s consider the recursive calculation of

Let s consider the recursive calculation of

4!. Because 4 is not equal to 0, we use the

second half of the definition:

• 4! = 4 * (4 - 1)! = 4 * 3!

• Of course, we can’t do the multiplication

Of course, we can t do the multiplication

yet, because we don’t know the value of

3!.

(7)
(8)

A Classic Example of Recursion

A Classic Example of Recursion

• Notice when the recursive calls stop. They stop

p

y

p

when we have reached a case for which we

know the answer without resorting to a recursive

definition In this example 0! = 1 directly from the

definition. In this example 0! = 1 directly from the

definition without having to resort to recursion.

• The case (or cases) for which an answer is

The case (or cases) for which an answer is

explicitly known is called the base case.

(9)

Base and General cases

Base and General cases

Base case

Base case

The case for which the solution

The case for which the solution

can be stated nonrecursively

General (recursive) case

The case for

General (recursive) case

The case for

which the solution is expressed in terms of

a smaller version of itself

a smaller version of itself

Recursive algorithm

A solution that is

d i t

f ( )

ll

expressed in terms of (a) smaller

(10)

Coding the Factorial Function

bli t ti i t f t i l(i t b ) public static int factorial(int number) {

if (number == 0)

return 1; // Base case l

else

return (number * factorial(number – 1)); // General case }

• Let’s trace this method with an original number of 4:

g

• Call 1 number is 4. Because number is not 0, the

else

branch is taken. The

return

statement cannot be

completed until the recursive call to factorial with

p

number – 1 as the argument has been completed.

• Call 2 number is 3. Because number is not 0, the

else

(11)

tracing the factorial method

• Call 3 number is 2. Because number is not 0, the

else

branch is taken. The

return

statement cannot be

l t d

til th

i

ll t f

t i l

ith

completed until the recursive call to factorial with

number – 1 as the argument has been completed.

• Call 4 number is 1. Because number is not 0, the else

branch is taken. The return statement cannot be

completed until the recursive call to factorial with

number – 1 as the argument has been completed.

• Call 5 number is 0. Because number equals 0, this call to

the method returns, sending back 1 as the result.

• Call 4 The return statement in this copy can now be

py

completed. The value to be returned is number

(12)

tracing the factorial method

• Call 3 The return statement in this copy can now be

completed. The value to be returned is number

(which is 2) times 1. This call to the method returns,

sending back 2 as the result.

• Call 2 The return statement in this copy can now be

py

completed. The value to be returned is number

(which is 3) times 2. This call to the method returns,

sending back 6 as the result.

• Call 1 The return statement in this copy can now be

completed. The value to be returned is number

(which is 4) times 6. This call to the method returns,

(

)

,

sending back 24 as the result.

• Because this is the last of the calls to factorial, the

recursive process is over. The value 24 is returned as

(13)
(14)

The iterative solution of factorial method

The iterative solution of factorial method

• The iterative solution is simpler and much more efficient because starting a new iteration of a loop is a faster operation than calling a starting a new iteration of a loop is a faster operation than calling a method.

• Let’s look at an iterative solution to the problem:

// Iterative solution

public static int factorial(int number) {

int value = 1;

for (int count = 2; count <= number; count++) {

value = value * count; }

(15)

Writing Recursive Methods

• You can use the following approach to write any recursive method:

1 G t t d fi iti f th bl t b l d (Thi f i

1. Get an exact definition of the problem to be solved. (This, of course, is the first step in solving any programming problem.)

2. Determine the size of the problem to be solved on this call to the method. On the initial call to the method, the size of the whole problem is expressed in the value(s) of the parameter(s)

in the value(s) of the parameter(s).

3. Identify and solve the base case(s) in which the problem can be expressed nonrecursively.

4. Identify and solve the general case(s) correctly in terms of a smaller case of the same problem a recursive call

of the same problem— a recursive call.

• In the case of factorial, the definition of the problem is summarized in the definition of the factorial function. The size of the problem is the number of values to be multiplied: n.

• The base case occurs when n = 0 in which case we take the nonrecursive • The base case occurs when n = 0, in which case we take the nonrecursive

path.

(16)

Count down example

Count down example

• /** Task: Counts down from a given positive integer.

g

p

g

* @param integer an integer > 0 */

public static void

countDown(

int

value)

{ System.out.println(value);

if

(value > 1)

(17)

Tracing the recursive call

countDown(3)

(18)

Tracing the recursive call

countDown(3)

Tracing the recursive call

countDown(3)

Note: the recursive method will use more

memory than an it ti th d d iterative method due

(19)

Example

Example

• Task: Compute the sum

Task: Compute the sum

1 + 2 + 3 + … + n for an integer n > 0

public static int sumOf(int n) { int sum;

if (n = = 1)( )

sum = 1; // base case

else

sum = sumOf(n - 1) + n; // recursive call

(20)

Tracing the recursive call

sumOf(3)

(21)

A Recursive Version of contains()method

()

• Let’s apply this approach to writing a recursive

version of the contains() method for our abstract

List class

List class.

public boolean contains(Object anEntry)

• The contains problem can be decomposed into

p

p

smaller problems by deciding if item is in the first

position of the list or in the rest of the list.

• More formally contains (anEntry=return (is

• More formally contains (anEntry=return (is

(22)

A Recursive Version of contains()method

ecu s e

e s o o co ta s() et od

• We can answer the first question just by comparing anEntry to entry[0].

• But how do we know whether anEntry is in the rest of the list? If only we had a • But how do we know whether anEntry is in the rest of the list? If only we had a

method that would search the rest of the list. But we do have one! The contains method searches for a value in a list.

• We simply need to start searching at position 1, instead of at position 0 (a smaller case).

• To do this, we need to pass the search starting place to contains() as a parameter. Each recursive call to contains() passes a starting location that is one location more than its own starting location.

• But how do we know when to stop?

• Within the code for the recursive contains() method we can use length 1 to mark • Within the code for the recursive contains() method we can use length – 1 to mark

the end of the list, so we can stop the recursive calls when our starting position is that value.

• We use the following private method specification to be called by contains () method • public boolean isThere (Object item, int startPosition);p ( j )

• // task: Determines if element matching item is on this list between • // startPosition and the end of the list

(23)

A Recursive Version of contains()method

ecu s e

e s o o co ta s() et od

• To search the whole list, we would invoke the method with the statement if (i Th ( E t 0))

if (isThere(anEntry, 0))

• The general case of this approach is the part that searches the rest of the list. This case involves a recursive call to isThere, specifying a smaller part

f th t b h d

of the array to be searched:

• return isThere(item, startPosition + 1);

• By using the expression startPosition + 1 as the argument, we have

effectively diminished the size of the problem to be solved by the recursive

ll Th t i hi th li t f t tP iti 1 t It 1 i

call. That is, searching the list from startPosition + 1 to numItems – 1 is a smaller task than searching from startPosition to numItems – 1.

• Finally, we need to know when to stop searching. In this problem, we have two base cases:

(1) h th l i f d ( t t ) d

• (1) when the value is found (return true), and

• (2) when we have reached the end of the list without finding the value

(24)
(25)

A Recursive Version of contains()method

ecu s e

e s o o co ta s() et od

• The code for the recursive isThere method follows

public boolean isThere (Object item, int startPosition)

// Returns true if item is on this list; otherwise, returns false {{

if (item.compareTo(Entry[startPosition]) == 0) // If they match return true;

else if (startPosition == (length – 1)) // If end of list else if (startPosition (length 1)) // If end of list return false;

(26)

Recursively Processing a Linked Chain

T

it

th d th t

h i

• To write a method that processes a chain

of linked nodes recursively

– Use a reference to the chain's first node as the

method's parameter

public void display()

• Then process

the first node

public void display()

{ displayChain(firstNode); System.out.println(); } // end display

– Followed by the

rest of the chain

private void displayChain(Node nodeOne) { if (nodeOne != null)

{ System.out.print(nodeOne.data + " "); displayChain(nodeOne next);

displayChain(nodeOne.next); }

(27)

Time Efficiency of Recursive Methods

Time Efficiency of Recursive Methods

• For the

For the

countDown

countDown

method

method

public static void countDown(int integer)

{ System out println(integer); { System.out.println(integer);

if (integer > 1)

countDown(integer - 1); } // end countDown

(28)

Towers of Hanoi

Towers of Hanoi

O f fi h b di k i h h i h

• One of your first toys may have been a disk with three pegs with colored circles of different diameters. If so, you probably spent countless hours moving the circles from one peg to another. If we put some constraints on how the circles or discs can be moved, we h d lt ll d th T f H i Wh th

have an adult game called the Towers of Hanoi. When the game begins, all the circles are on the first peg in order by size, with the smallest on the top. The object of the game is to move the circles, one at a time, to the third peg. The catch is that a circle cannot be

l d t f th t i ll i di t Th iddl

placed on top of one that is smaller in diameter. The middle peg can be used as an auxiliary peg, but it must be empty at the beginning and at the end of the game.

• The circles can only be moved one at a time.y

• To get a feel for how this might be done, let’s look at some sketches of what the configuration must be at certain points if a solution is possible. We use four circles or discs. The beginning configuration is:

(29)
(30)

Towers of Hanoi

Towers of Hanoi

• To move the largest circle (circle 4) to peg

To move the largest circle (circle 4) to peg

3, we must move the three smaller circles

to peg 2 (this cannot be done with 1

to peg 2 (this cannot be done with 1

move). Then circle 4 can be moved into its

final place:

(31)
(32)
(33)
(34)

Towers of Hanoi

Towers of Hanoi

• Algorithm for solution with 1 disk as the

Algorithm for solution with 1 disk as the

base case

Algorithm solveTowers(numberOfDisks, startPole, tempPole, endPole) if (numberOfDisks == 1)

Move disk from startPole to endPole

Move disk from startPole to endPole

else

{

solveTowers(numberOfDisks-1, startPole, endPole, tempPole)

Move disk from startPole to endPole

(35)

Fibonacci numbers

Fibonacci numbers

• First two numbers of sequence are 1 and 1

q

• Successive numbers are the sum of the previous two

– 1, 1, 2, 3, 5, 8, 13, …

• This has a natural looking recursive solution

• This has a natural looking recursive solution

– Turns out to be a poor (inefficient) solution

• The recursive algorithm

Algorithm

Fibonacci(n)

if

(n <= 1)

return

1

else

(36)

Fibonacci numbers

Fibonacci numbers

Time efficiency grows exponentially with n

References

Related documents

Contradicting this explanation, however, are data that coronary blood flow is increased, not decreased, in patients with septic shock, and that elevated troponin levels in a majority

Upgrading to Project Server 2013, from previous versions, to an On-Premises Solution is a process that will require a dedicated Project Server 2013 environment.. It will also

Bell, a fitness enthusiast, buys an existing exercise center, Body Firm..

If necessary and only prior to activation, 1 adult VIP PASS may be exchanged at the Verbier, Le Châble or La Tzoumaz tourist offices for 2 children's VIP PASSES (only valid

We concluded that HRV-guided running training reduced tension, depression, anger, fatigue, and total mood disturbance scales of mood state, and stress factors of the

The scary truth is that both non-violent and violent porn make users more likely to support vio- lence against women and to believe that women enjoy being raped, [13] and

The second definition of the opportunity cost of time follows from a structural framework that links moral norms, household production functions, and household choices to

This paper focuses on one such way to perform input data validation, by marrying web form design with programming language specification languages, such as the Java Modeling