16-jun-15 recursion. 2 definitions i a recursive definition is a definition in which the thing being...

24
Mar 27, 2 022 Recursion

Post on 20-Dec-2015

220 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

Apr 18, 2023

Recursion

Page 2: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

2

Definitions I

A recursive definition is a definition in which the thing being defined occurs as part of its own definition

Example: An atom is a name or a number A list consists of:

An open parenthesis, "(" Zero or more atoms or lists, and A close parenthesis, ")"

Page 3: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

3

Definitions II

Indirect recursion is when a thing is defined in terms of other things, but those other things are defined in terms of the first thing

Example: A list is: An open parenthesis, Zero or more S-expressions, and A close parenthesis

An S-expression is an atom or a list

Page 4: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

4

Recursive functions...er, methods

The mathematical definition of factorial is:

We can define this in Java as: long factorial(long n) {

if (n <= 1) return 1; else return n * factorial(n – 1);}

This is a recursive function because it calls itself Recursive functions are completely legal in Java

1, if n <= 1n * factorial(n-1) otherwise

factorial(n) is

Page 5: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

5

Anatomy of a recursion

long factorial(long n) { if (n <= 1) return 1; else return n * factorial(n – 1);}

Base case: does some work without making a recursive call

Recursive case: recurs with a simpler parameter

Extra work to convert the result of the recursive call into the result of this call

Page 6: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

6

Infinite recursion

The following is the recursive equivalent of an infinite loop: int toInfinityAndBeyond(int x) {

return toInfinityAndBeyond(x);}

While this is obviously foolish, infinite recursions can happen by accident in more complex methods

Page 7: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

7

Another problem

Consider the following code fragment: int n = 20;

...int factorial() { if (n <= 1) return 1; else { n = n – 1; return (n + 1) * factorial(); }}

Does this work? Changing a nonlocal variable makes the program much more

difficult to understand

Page 8: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

8

Why recursion?

For something like the factorial function (which is sort of the “Hello world” of recursion, it’s faster and just as simple to use a loop

For working with inherently recursive data, such as arithmetic expressions, recursion is much simpler

Example: To evaluate the expression (2 + 3) * (4 + 5), you must first evaluate the expressions (2 + 3) and (4 + 5)

Recall the definition of a list: A list consists of:

An open parenthesis, "(" Zero or more atoms or lists, and A close parenthesis, ")"

Lists are also inherently recursive

Page 9: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

9

Understanding recursion

The usual way to teach recursion is to “trace through” a recursion, seeing what it does at each level

This may be a good way to understand how recursion works...

...but it's a terrible way to try to use recursion There is a better way

Page 10: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

10

Base cases and recursive cases

Every valid recursive definition consists of two parts: One or more base cases, where you compute the answer

directly, without recursion One or more recursive cases, where you do part of the work,

and recur with a simpler problem

Page 11: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

11

Information hiding

function spread (int A[], int size) { int max, min; sort(A, size); min = A[0]; max = A[size - 1]; return max - min;}

Can you understand this function without looking at sort?

Page 12: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

12

Stepping through called functions

Functions should do something simple and understandable

When you try to understand a function, you should not have to step through the code of the functions that it calls

When you try to understand a recursive function, you should not have to step through the code of the functions it calls

Page 13: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

13

We have small heads

It's hard enough to understand one level of one function at a time

It's almost impossible to keep track of many levels of the same function all at once

But you can understand one level of one function at a time...

...and that's all you need to understand in order to use recursion well

Page 14: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

14

The four rules

Do the base cases first Recur only with a simpler case Don't modify nonlocal variables* Don't look down

* Remember, parameters count as local variables

Page 15: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

15

Do the base cases first

Every recursive function must have some things it can do without recursion

These are the simple, or base, cases Test for these cases, and do them first This is just writing ordinary, nonrecursive code

Page 16: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

16

Recur only with a simpler case

If the problem isn't simple enough to be a base case, break it into two parts: A simpler problem of the same kind (for example, a smaller

number, or a shorter list) Extra work not solved by the simpler problem

Combine the results of the recursion and the extra work into a complete solution

“Simpler” means “more like a base case”

Page 17: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

17

Example 1: member

Is value X a member of list L ? boolean member(X, L) { if (L is the empty list)

return false; // this is a base case if (X equals the first element in L)

return true; // another base case return member(X, L - first element);

// simpler because more like empty list}

Page 18: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

18

Example 2: double

Double every element of a list of numbers function double(L) { if (L is the empty list)

return the empty list; // base case else {

L2 = double (L - first element); // recur D = 2 * first element in L; // extra work return (list made by adding D to L2); // combine

}}

Page 19: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

19

It's OK to modify local variables

A function has its own copy of local variables parameters passed by value (which are effectively local

variables) Each level of a recursive function has its own copy

of these variables and parameters Changing them at one level does not change them

at other levels One level can't interfere with another level

Page 20: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

20

It's bad to modify objects

There is (typically) only one copy of a given object If a parameter is passed by reference, there is only

one copy of it If such a variable is changed by a recursive function,

it's changed at all levels The various levels interfere with one another This can get very confusing Don't let this happen to you!

Page 21: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

21

Don't look down

When you write or debug a recursive function, think about this level only

Wherever there is a recursive call, assume that it works correctly

If you can get this level correct, you will automatically get all levels correct

You really can't understand more than one level at a time, so don't even try

Page 22: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

22

MEMBER again boolean member(X, L) { if (L is the empty list)

return false; This says: if list L is empty, then X isn’t an element of L Is this a true statement?

if (X equals the first element in L) return true;

This says: if X = the first element in L, then it’s in L Is this a true statement?

return member(X, L - first element); This says: if X isn’t the first element of L, then X is in L if and

only if X is in the tail of L Is this a true statement? Did we cover all possible cases? Did we recur only with simpler cases? Did we change any global variables? We’re done!

Page 23: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

23

Reprise

Do the base cases first Recur only with a simpler case Don't modify nonlocal variables Don't look down

Page 24: 16-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:

24

The End