Title: Recursion
1Recursion
2Recursion
- What is recursion?
-
- In the context of a programming language - it is
simply an already active function (or subprogram)
being invoked by itself directly or being invoked
by another function (or subprogram) indirectly.
3Types of Recursion
- Direct Recursion
- function alpha()
-
- alpha
-
- Indirect (or Mutual) Recursion
- function alpha()
-
- beta
-
- function beta()
-
- alpha
-
- Is this even possible in C?
4Illustration
- Suppose we wish to formulate a list of
instructions to explain to someone how to climb
to the top of a ladder. - Consider the following pseudo-code statements -
- Iterative statements
Recursive statements - function Climb_Ladder()
function Climb_Ladder() - begin
begin - while not (at the top)
if steps_remaining 0 - do move up one rung
then stop - stop
else begin - end
move
up one rung -
Climb_Ladder -
end -
end
5Why use recursion?
- There is a common belief that it is easier to
learn to program iteratively, or to use
non-recursive functions, than it is to learn to
program recursively. - Some programmers report that they would be
fired if they were to use recursion in their
jobs. - In fact, though, recursion is a function-based
technique for implementing iteration.
6Hard to argue conclusively for recursion!
- However, recursive programming is easy once one
has had the opportunity to practice the style. - Recursive programs are often more succinct,
elegant, and easier to understand than their
iterative counterparts. - Some problems are more easily solved using
recursive functions than iterative ones.
7Example Fibonacci Numbers
- Fibonacci numbers have an incredible number of
properties that crop up in computer science. - There is a journal, The Fibonacci Quarterly,
that exists for the sole purpose of publishing
theorems involving Fibonacci numbers. - Examples
- 1. The sum of the squares of two consecutive
Fibonacci numbers is another Fibonacci number. - 2. The sum of the first n Fibonacci numbers is
one less than Fn2 - Because the Fibonacci numbers are recursively
defined, writing a recursive function to
calculate Fn seems reasonable. - Also, from my earlier argument, we should
expect the algorithm to be much more elegant and
concise than an equivalent iterative one. - Consider an iterative solution!
8Non-recursive Fibonacci Numbers
-
- int fibonacci(int n)
-
- int fnm1, fnm2, fn
- int i
-
- if (n lt1)
- return n /F0 0 and F1 1/
- else
-
- fnm2 0
- fnm1 1
- for (i 2 i lt n i)
-
- fn fnm1 fnm2
- fnm2 fnm1
- fnm1 fn
-
-
Note F0 0 F1 1 F2 1 F3 2 F4 3 .
. .
9Fibonacci Numbers
- Recursive Definition
- Fib(n)
-
- Series 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
- C
- int fib(int n)
-
- if (n 0)
- return 0
- else if (n 1)
- return 1
- else return(fib(n-1) fib(n-2))
10The underlying problem with the recursive
function is that it performs lots of redundant
calculations.
Example on a reasonably fast computer, to
recursively compute F40 took almost a minute. A
lot of time considering that the calculation
requires only 39 additions. Example to compute
F5 F5 F4 F3
F3 F2 F2 F1 F2 F1 F1 F0
F1 F0 F1 F0 It turns out
that the number of recursive calls is larger than
the Fibonacci number were trying to calculate -
and it has an exponential growth
rate. Example n40, F40 102,334,155 The
total number of recursive calls is greater than -
300,000,000
11Solving Problems
- We encourage students to solve large problems
by breaking their solutions up into smaller
problems - These smaller problems can then be solved and
combined (integrated) together to solve the
larger problem. - Referred to as Stepwise Refinement,
Decomposition, Divide-and-conquer
12Basis of Recursion
- If the subproblems are similar to the original --
then we may be able to employ recursion. - Two requirements
- (1) the subproblems must be simpler than
the original problem. - (2) After a finite number of subdivisions, a
subproblem must be encountered that can be
solved outright.
13How is memory managed?
- Consider the following C program
- int main(void)
-
- int i, j, k
- . . .
- three
- . . .
- return 0
-
- void one()
-
- float x, y, z
-
- . . .
- return
-
- Say that the main program has invoked function
three, three has invoked two, and two has invoked
one. - Recall that parameters and local variables are
allocated memory upon entry to a function and
memory is deallocated upon exit from the function
. - Thus, the memory stack would currently look like
14Is memory managed differently for recursion?
- No!!
- Consider the following C program
- void main()
-
- int i, j, k
- . . .
- recursiveOne
- . . .
-
- void recursiveOne()
-
- float x,y,z
- . . .
- recursiveOne
- . . .
- Parameters and local variables are still
allocated memory upon entry to a function and
deallocated upon exit from the function. - Thus, during the recursion, the memory stack
would look like
15Example
- Some escape mechanism must be present in the
recursive function (or subprogram) in order to
avoid an infinite loop. - Iterative functions (with infinite loops) are
terminated for exceeding time limits. - Recursive functions (with infinite loops) are
terminated due to memory consumption.
16Observation!
- include ltstdio.hgt
-
- int main(void)
-
- doIt()
-
- void doIt()
-
- int x100/100 element array/
-
- static int count 1
-
- printf("Here - d\n",count)
- count
- doIt()
17Iteration
Entry
Initialization
Done
Decision
Return
Not Done
Computation
Update
18Recursion
Entry
Prologue (SAVE state of calling program
Save formal parameters, local variables, return
address
Test
Intermediate Level (continue)
Partial computation
Body
Stop recursion
Procedure call To itself
Final Computation
Epilogue (restore SAVE state)
Restore (most recently Saved) formal parameters,
Local variables, return address
Exit
To return address
19Consider an Example(Summing a series of integers
from 1 to n)
int main(void) int sum int n 10
sum iterativeSum(n) printf("Sum d"
sum) int iterativeSum(int n) int
tempSum n while ( n gt 1) n--
tempSum tempSum n return
(tempSum)
int main(void) int sum int n 10
sum recursiveSum(n) printf("Sum d"
sum) int recursiveSum(int n) if (n lt
1) return n else return
(nrecursiveSum(n-1))
20Formal Representation Methods
- Used by computer scientists for producing a
mathematically rigorous representation of a set
of user requirements. - Two classes of Representation Methods
- State oriented notations
- Examples (Decision Tables, Finite-state Machines)
- Relational notations
- Examples (Recurrence Relations, Algebraic Axioms)
21Using representational notations Recall the
earlier example of summing the integers from 1
to n
- This can be described as a series using the
following representation - Sum n (n-1) (n-2) ... 1 or
-
- Alternatively, recursive definitions (recurrence
relations) can be employed -
- Sum(n)
22Consider another example -Computing Factorials
- Definitions
- Iterative -
- n!
- Recursive -
- n!
int factorial(int n) if (n 0)
return 1 else return ( n
factorial(n-1))
23Computing a power (xn)
- Recall that C does not provide an exponentiation
operator the function pow in the Math library
must be used (e.g., pow(2,3)) - Calculating powers can also be done using the
relationship - xn exp(n ln(x))
- Could also be done recursively
- Recursive Definition power(x,n)
float power(double x,int n) if (n 0)
return 1.0 else if (n 1)
return x else return ( x
power(x,n-1))
24Summing the elements of an array named list that
contains n values.Assuming lower bound of 0 as
for C
- Recursive definition
-
- sum(list,n)
-
C int sum(int list, int n) /list
is the array to be summed, n represents the
number of elements currently in the array
/ if (n 1) return list0 else
return (listn-1 sum(list,n-1))
25Using Scope!
- C
- int sum(int n)
-
- / access the array (in this case list) to be
summed - through scope, n represents the number of
elements - currently in the array /
- if (n 1)
- return list0
- else
- return (listn-1 sum(n-1))
-
-
26Sequentially search the elements of an array for
a given value(known to be in the array)
- Recursive Definition -
-
- search(List, i, Value)
- C
- int search(int list, int i, int value)
-
- if (listi value)
- return i
- else
- return search(list,i1,value)
-
- Note (1) Assumes that the desired value is in
the array, - (2) Initial call is positionOfValue
search(list,0,value)
27Sequentially search the elements of an array for
a given value(maybe not in the array)
- Recursive Definition -
-
- search(list,i,value,numEls)
- C
- int search(int list, int i, int value, int
numEls) -
- if (Listi value)
- return i
- else if (i numEls)
- return -99
- else
- return search(list,i1,value,n
umEls) -
- Note (1) Assumes that the desired value may not
be in the array, - (2) Initial call is positionOfValue
search(list,0,value,numEls)
28Other Example
- Converting an integer value to binary -
-
-
- void convertToBinary(int x)
-
- int t x/2 /integer divide, truncate
remainder / - if (t ! 0)
- convertToBinary (t)
- printf(d,x2)
-
29Primitive Recursion vs Non-primitive Recursion
- All examples that we have seen to this point have
used primitive recursion. - Non- primitive recursion
-
- Ack(m,n)
30Disadvantages of Recursion
- Function calls may be time-consuming.
- Recursive functions may take longer to run.
- More dynamic memory is used to support recursion.