Download - 04 CSC335 Chapter10b(Recursion Part 1)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
1/58
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
2/58
Dr. Ahmad R. Hadaegh
A.R. Hadaegh National University Page 2
Recursion
- A word that strikes fear into novice computerscientists
- and (usually) excitement into the experienced
ones
- Before we begin
Many people hate recursion!
Some people think Its difficult to understand
and hard to use
- But this isnt true! Its just something that has
to be viewed the right way
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
3/58
Dr. Ahmad R. Hadaegh
A.R. Hadaegh National University Page 3
Recursion
- A different way of stating problems than we
have seen so far
- The term Recursion involves self-reference
wherever it is used
e.g. a recursive definition: something defined in
terms of itself
- Well begin by looking at a recursive definition.
Think of defining an exponential relationship
between two variables X and Y
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
4/58
Dr. Ahmad R. Hadaegh
A.R. Hadaegh National University Page 4
Exponentiation
- xy= X* X* X* X* X* X (where we have Y number of Xs)
- Thats the normal way of thinking of it
(the iterative way)
- But we can define xyanother way:
xy= X if Y = 1 (case 1)
xy= xy-1 * X if Y > 1 (case 2)
- This is an equally valid way of defining xy
- Its a recursive definition: exponentiation is
defined in terms of exponentiation
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
5/58
Dr. Ahmad R. Hadaegh
A.R. Hadaegh National University Page 5
Recursive Definitions
- What happens if we dont have case 1?
- Our definition never stops! We define X2as
X* X1, and X1as X* X0, and X0as X* X-1, and so
on
- We call case 1 the Base Case
- Case 2 is the Recursive Case
- Any recursive definition is a combination of
one or more base cases and one or more
recursive cases
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
6/58
Dr. Ahmad R. Hadaegh
A.R. Hadaegh National University Page 6
More Examples
- Factorial - N! = N*(N-1)** 2* 1 (N Terms)- But also:
N! = 1 if N=1 (base case)
N! = N*(N-1)! if N > 1 (recursive case)
- Fibonacci Numbers: 1st two are 1 and 1,
each higher number is the sum of the
previous two
This is a recursive definition:
Fib(N) = 1 (if N=1 or N=2)
Fib(N) = Fib(N-1) + Fib(N-2) (for any N>2)
1 1 2 3 5 8
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
7/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 7
- Where is the advantage of recursion?
- Easy to program compared to the iterative ones
- How do you code these?
- Generally, once youve made a precise definition,
all you have to do is encode it directly
- thats the beauty of recursion!
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
8/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 8
Power - Recursively!int Rpower( int x, int y)
{
// returns xyrecursivelyif (y == 1)
return x;
else
{int p = Rpower( x, y-1);
return x * p;
}
}
- This is a Recursive Function - one
that calls
itself
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
9/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 9
- in the body of the function:
if (y == 1)return x;
else
return x* Rpower(x, y-1);
- It looks like were getting everything in thehigher cases done mysteriously for us...
- Wheres the loop? Are we getting
something for free? (no)
- Theres really no mystery to recursive
functions - everything comes down from
how function calls work
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
10/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 10
A Reminder about Functions
- When we call a function, what happens?
Execution of caller halts at the function call
We allocate parameters and local vars for the
function
Parameters get their argument valuesWe execute the functions code
The function returns
Local vars and parameters are destroyed
Execution resumes precisely where it left in thecaller, possibly with a value returned by the
function
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
11/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 11
How Does This Explain Recursion?
- EXACTLY the same thing happens in arecursive function!
- Lets go through a call to Rpower and see
this. Suppose our main program says:
cout
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
12/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 12
Explaining Recursion
- Rpower gets executed (call this call_1):
if (y == 1)
return x;
else
return x* Rpower( x, y-1);
- The else gets executed, and were asked to
return x*Rpower(x, y-1)
- This is a function call - but to the same
function were in
- Its treated like any other!
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
13/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 13
Explaining Recursion
- We halt where we are - in the middle of the
x* Rpower(x, y- 1) expression in call_1
- We call function Rpower again, and allocate two
more parameters, x and yThese are new, DIFFERENT parameters from the
x and y we are currently using
They just happen to have the same names!
- These parameters get the values 2 (the x in
call_1 thats passed) and 2 (the result of y-1 in
call_1)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
14/58
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
15/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 15
Continuing the Example:
- Rpower now executes (with parameters 2,2)
- Were finding a solution to a problem thats a
little bit smaller than the initial one (2,3)
if (y == 1)
return x;
else
return x* Rpower( x, y- 1);
- Here, similarly, the else part of our code gets
executed and were asked to return
x*Rpower( x, y-1)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
16/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page16
Continuing the Example
- We halt where we are - in the middle of thex* Rpower(x, y-1) expression
- We call function Rpower, and allocate two
parameters, x and y
Yet another new, DIFFERENT x and y
- These parameters get the values 2 (the x in
call_2 thats passed) and 1 (the result of y-1
in call_2)
- Rpower then runs - call it call_3
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
17/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 17
- The systems stack of parameters grows
x = 2
y = 2
x = 2
y = 3Call_1
Call_2
- You can see that this cycle would simply repeat, with
each new y parameter becoming one smaller
x = 2
y = 1Call_3
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
18/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 18
- When Rpower runs, this time y finally is 1
if (y == 1)return x;
else
return x* Rpower( x, y- 1);
- And this time there is no recursive call
- If this case never came up, wed have
infinite recursion - just like an infinite loop
(but wed eventually run out of memory for
parameters!)
- We simply return x (that has the value of 2).
Where does it go?
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
19/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 19
Returning Values
- Remember - we return back precisely wherewe left in the caller
- Call_3s parameters are de-allocated and we return
the value 2
x = 2
y = 2
x = 2
y = 3Call_1
Call_2
x = 2
y = 1Call_3
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
20/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 20
Returning Values
- Remember - we return back precisely where weleft in the caller
- It was call_2 where we left off.
x = 2
y = 2
x = 2
y = 3Call_1
Call_2
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
21/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 21
Back in Call_2...
- Remember, we invoked call_3 using the statement:
return x* Rpower(x, y-1);
- where x and y are the values from call_2s
parameters: x=2 and y=2
- When we return from call_3, we are in the middle of themultiply in call_2, and the value returned (2) is used in the
multiplication
- We get 4, and return it - to call_1.
x = 2
y = 2
x = 2
y = 3Call_1
Call_2
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
22/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 22
Returning Values
- Again, we return back precisely where weleft in the caller
x = 2
y = 2
x = 2
y = 3Call_1
Call_2
- Call_2s variables are de-allocated, we return the
value 4
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
23/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 23
Returning Values
- Again, we return back precisely where weleft in the caller
- And we resume exactly where we left off
in call_1
x = 2y = 3Call_1
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
24/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 24
Back in Call_1
- Remember, we invoked call2 using the
statement:
return x* Rpower(x, y-1);
- where x and y are the values from call_1s
parameters: x=2 and y=3
- When we return from call_2, we are in the middle
of the multiply in call_1, and the value returned (4)is used in the multiplication
- We get 8, and return it to the main program
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
25/58Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 25
The Main Program
- Then prints the value out (we used the call in
a cout)
- The big thing to notice with all this -
Mechanically there is nothing new here!
- If you dont understand these you will not
understand how recursive functions work
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
26/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 26
The Abstraction
- What is new is the abstraction were performing -getting used to thinking of an invocation of a functionfrom itself as running a separate copy
- Remember, all were doing is using some method ofbreaking the problem into smaller parts, continuinguntil the parts are of a trivial size, and thencombining the pieces
- Once youve found a method of breaking the
problem down into simpler bits, and found what thetrivial cases are, programming it is easy!
- Just remember that you do eventually have to hit thesimple cases, or you get infinite recursion
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
27/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 27
- Remember that youre never getting
something for nothing when it comes torecursion
- It looks that way because you dont see a loop
- theres no explicit iteration
- The function is just getting called repeatedly
until the problem is completely broken down,
and solves the problem as the simpler
solutions are combined
- you just dont see that unless you look for it!
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
28/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 28
Recursive Linear Search
- Can implement linear search in a purelyfunctional manner
no assignment statements or loops
just function calls
- Implement a function
bool linsearch (const vector L, int pos, int key);
which returns true if key is found in L at or after
position pos and false otherwise.
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
29/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 29
Recursive Linear Search
- To break this problem down recursively, notethat the problem is easy when
1) L.size() == 0, in which case we can return false
2) L [pos] == key, in which case we can return true
- When (1) and (2) are both false, then if key
exists in L, then it must be in one of positions
L[pos+1]... L[L.size()-1]
- this can be implemented by the function call
linsearch(L, pos+1, key)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
30/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 30
Recursive Linear Search
// C++ code for recursive linear search
bool linsearch(const vector< int>& L,
int pos, int key)
{
if (L.size()== 0 || pos >= L.size())
return false;
else if (L[pos]== key)
return true;
elsereturn linsearch( L, pos+1, key);
}
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
31/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 31
Another Example
- This time, one that doesnt perform a
calculation
- Think of reverse-printing a file-dumping it out
backwards
- cant print the first item until weve read the
whole thing
- Iteratively, you would use an array
- What about recursively?
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
32/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 32
Recursively Reversing a File
- What would a recursive description of
reverse-printing a file look like?
- Intuitively, the termination should be end-of-file
- To recursively reverse-print a file, read an
item, reverse-print the rest of the file, and then
print out the original item
- A nice recursive definition, and again, easy to
program. Well assume a file of integers
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
33/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 33
Reverse- Print a File Recursively
void reverse(ifstream& inputdata)
{
int item;
inputdata >> item; // get item
if (! inputdata.eof())
{reverse(inputdata); // reverse rest of file
cout
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
34/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 34
General Idea
- Trace through this yourself, but the general
idea of whats happening is:
We read the first item into local var item
Calling reverse generates a new local var item,
and repeats the process
we keep recursing until end-of-file, and only then
print off the most recently-read item
when we return, we return to the last call to
reverse, with the previous item, and print that
and so on, all the way back up to the top
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
35/58
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
36/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 36
Recursion
vs.Iteration
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
37/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 37
Recursion vs. Iteration
- Now that we know both, how do they compare?
- Take a problem like power, program it
recursively and iteratively - Which will be faster?
- As far as analyzing the algorithm goes, they"theoretically" do the same amount of real work
- Theres extra overhead for the recursion -
the stacking and unstacking of parameters, andeverything else that goes along with the function-
calling process
generally makes it slower
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
38/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 38
Recursive Binary Search
- A little while ago, we saw how to search
through a sorted array for a key using binary
search
- assume array sorted in increasing order
- This is an algorithm which is naturally stated
recursively
- First, recall the iterative solution
int binsearch( const vector< int>& A, int key)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
39/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 39
( , y){
int mid; // the middle point of the array
int first= 0; // start of section in array
int last= A.size()- 1; // end of section
bool found = false; // assume not found to start
while (first
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
40/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 40
Recursive Binary Search
- What's really happening in here?bisect the current range first... last at mid
if A[mid] == key we are done
if A[ mid] < key then key is in upper half of region
first... last
- continue by searching upper half mid+1... last
if key < A[mid] then key is in lower half of array ifit is in array at all
- continue by searching lower half first...mid- 1
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
41/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 41
Recursive Binary Search
- This is a recursive descriptionalgorithm defined in terms of itself
- Base Case:
- if first > last we are finished- key is not found
- otherwise, compute mid and compare A[mid] to
key
- recursively search lower or upper half accordingly
- return result of search
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
42/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 42
Recursive Binary Search
int binsearch (const vector< int>& A, int key
int first, int last){
if (first> last)
return -1; // key not found (null vector)
else
{ int mid = (first+ last)/ 2; // define mid- point
if (A[mid] == key)
return mid; // found it
if (A[mid] < key) // search upper half of region
return binsearch( A, key, mid+1, last);
else // search lower half of region
return binsearch( A, key, first, mid-1);
}
}
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
43/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 43
Recursive Binary Search
- Consider the sorted arrayindex: 0 1 2 3 4 5 6 7
value: 2 3 5 7 11 13 14 17
Start by calling binsearch( A, 11, 0, 7)- mid = 3 and A[3] < 11 // key in A[ 4]... A[ 7]
call binsearch( A, 11,4,7)
- mid = 5 and A[5] > 11 // key in A[ 4].. A[ 4]
call binsearch( A, 11, 4, 4)
- mid = 4 and A[4]==11
- Found it
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
44/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 44
Mergesort
- Sometimes a recursive solution is in fact the
fastest solution
- An important example of this is mergesort
one of the fastest known "comparison based"
sorting algorithms
also extremely fast in practice
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
45/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 45
Mergesort
- Main idea
break the array into two unsorted arrays of equal
size
sort each side recursively
merge the two sorted halves into a single sortedarray
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
46/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 46
Mergesort
- For example, on array
A = { 5, 9, 3, 13, 2, 6, 4, 1, 3, 7 }
left = { 5, 9, 3, 13, 2 }
right = { 6, 4, 1, 3, 7 }
Recursively sort left to {2, 3, 5, 9, 13}
Recursively sort right to {1, 3, 4, 6, 7}
Merge the two sorted arrays into a single sorted
array:
{ 1, 2, 3, 3, 4, 5, 6, 7, 9, 13 }
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
47/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 47
Mergesort: merging
- Aside from the recursion, the only operation which
needs to be accomplished is to merge two sorted
lists
- Idea: maintain a "pointer" into each sorted array
at each step, append the smallest element pointed to
onto the final array
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
48/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 48
Mergesort: merging
Step 1:
sort_ left = { 2 , 3, 5, 9, 13 }
sorted_ right = { 1 , 3, 4, 6, 7 }
sorted_ array = {}
Step 2:
sort_ left = { 2 , 3, 5, 9, 13 }
sorted_ right = { 1, 3 , 4, 6, 7 }
sorted_ array = { 1 }
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
49/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 49
Step 3:
sort_ left = { 2, 3 , 5, 9, 13 }
sorted_ right = { 1, 3 , 4, 6, 7 }
sorted_ array = { 1, 2 }
Step 4:
sort_ left = { 2, 3, 5 , 9, 13 }sorted_ right = { 1, 3 , 4, 6, 7 }
sorted_ array = { 1, 2, 3 }
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
50/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 50
Step 5:
sort_ left = { 2, 3, 5 , 9, 13 }sorted_ right = { 1, 3, 4 , 6, 7 }
sorted_ array = { 1, 2, 3, 3 }
Step 6:
sort_ left = { 2, 3, 5 , 9, 13 }
sorted_ right = { 1, 3, 4, 6 , 7 }
sorted_ array = { 1, 2, 3, 3, 4 }
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
51/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 51
Step 7:
sort_ left = { 2, 3, 5, 9 , 13 }
sorted_ right = { 1, 3, 4, 6 , 7 }
sorted_ array = { 1, 2, 3, 3, 4, 5 }
Step 8:
sort_ left = { 2, 3, 5, 9 , 13 }sorted_ right = { 1, 3, 4, 6, 7 }
sorted_ array = { 1, 2, 3, 3, 4, 5, 6 }
Step 9:
sort_ left = { 2, 3, 5, 9 , 13 }
sorted_ right = { 1, 3, 4, 6, 7 }
sorted_ array = { 1, 2, 3, 3, 4, 5, 6, 7 }
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
52/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 52
Step 10:
sort_ left = { 2, 3, 5, 9, 13 }
sorted_ right = { 1, 3, 4, 6, 7 }
sorted_ array = { 1, 2, 3, 3, 4, 5, 6, 7, 9 }
Step 11:
sort_ left = { 2, 3, 5, 9, 13 }
sorted_ right = { 1, 3, 4, 6, 7 }
sorted_ array = { 1, 2, 3, 3, 4, 5, 6, 7, 9, 13 }
Mergesort: merging
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
53/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 53
Mergesort: mergingvector< int> merge( const vector< int>& L,
const vector< int>& R)
{
int Lptr= 0, Rptr= 0; vector< int> A;
while (Lptr< L.size() || Rptr< R.size())
{
if ((Lptr< L.size()) && ((Rptr>= R.size() || L[Lptr]
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
54/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 54
Mergesort
- The recursive mergesort routine itself is very
simple
vector mergesort(const vector& A)
{
vector< int> left, right;
if (A.size()
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
55/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 55
- Again, follow the recursion
- We split the array into two
- And each half into two recursively
- And so on - eventually it gets split into N listsof a single element each
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
56/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 56
- For each split at the end, a pair of elements is
merged
- Then we merge the pairs, and then the quartets
- And so on until one merge of two large lists at the
end
- This is a by far faster than some other sorts like
bubble sort or insertion sort algorithm
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
57/58
Dr. Ahmad R. HadaeghA.R. Hadaegh National University Page 57
Some Closing Thoughts
- Some problems can be stated iteratively orrecursively
- In many cases a problem is much more
naturally stated in one paradigm, and
requires a lot of ugliness to state it in the
other
- Some problems are much more easilyprogrammed recursively than iteratively
(e.g. the Towers of Hanoi example in the
book)
-
8/13/2019 04 CSC335 Chapter10b(Recursion Part 1)
58/58
Some Closing Thoughts
- Other problems will have recursive solutionsthat will be less attractive to program than
iterative ones - or not attractive enough to
justify the extra overhead
- Recursion is an important tool in your
programmers tool box. Like anything else,
use it when it is well- suited!!!