Loading...

PPT – Introduction to Recursion PowerPoint presentation | free to download - id: 74d9da-MWZmN

The Adobe Flash plugin is needed to view this content

Introduction to Recursion

CSCI 3333 Data Structures

by Dr. Bun Yue Professor of Computer

Science yue_at_uhcl.edu http//sce.uhcl.edu/yue/ 201

3

Acknowledgement

- Mr. Charles Moen
- Dr. Wei Ding
- Ms. Krishani Abeysekera
- Dr. Michael Goodrich

Recursion

- Recursion is a way to combat complexity and solve

problems. - Solving a problem by
- solving the problem for trivial cases, and
- solving the same problem, but with smaller sizes.

Recursive Definition

- A recursive definition a definition in terms of

itself. - Example
- 0 is a natural number.
- If x is a natural number, then x1 is a natural

number. (or x is a natural number if x-1 is a

natural number).

Mathematical Induction

- Proof by Induction is recursive in nature.
- To prove S(n) for all n 1, 2, 3.
- Show
- S(n) is true for n 1.
- If S(k) is true for all k from 1 to n-1, then

S(n) is true

Recursive Methods

- A recursive method may call itself.
- Example factorial.
- Iterative definition
- n! n . (n-1) . (n-2) 3 . 2 . 1
- Recursive definition

Factorial Implementation Fac-1

- Found here in C
- int factorial(int number)
- int temp
- if (number lt 1) return 1
- temp number factorial(number - 1)
- return temp
- What do you think?

Another Implementation Fac-2

- // recursive factorial function in Java
- public static int recursiveFactorial(int n)
- if (n 0) return 1 // base case
- else return n
- recursiveFactorial(n- 1)
- // recursive case
- // By Goodrich
- What do you think?

Content of a Recursive Method

- Base case(s) exit conditions
- Values of the input variables (exit conditions)

for which we perform no recursive calls are

called base cases (there should be at least one

base case). - Every possible chain of recursive calls must

eventually reach a base case. - Recursive calls recursive conditions
- Calls to the current method.
- Each recursive call should be defined so that it

makes progress towards a base case.

Visualizing Recursion

Example recursion trace

- Recursion trace
- A box for each recursive call
- An arrow from each caller to callee
- An arrow from each callee to caller showing

return value

Tips on Recursive Analysis

- Identify exit and recursive conditions.
- Ensure that the conditions cover all input ranges.

Input Range Analysis of Fac

- Fac-1 and Fac-2 n (or number) has the type of

int. - Fac-2 may be caught in circularity forever for

negative numbers. - This is especially serious in Java as it does not

support unsigned int.

Complexity Analysis

- To analyze the time complexity of a recursive

routine, a recurrence relation may need to be

identified and solved. - E.g. for factorial
- T(0) d
- T(N) T(N-1) c
- Solving by substitution T(N) cN d O(N)

Reversing an Array

- Algorithm ReverseArray(A, i, j)
- Input An array A and nonnegative integer

indices i and j - Output The reversal of the elements in A

starting at index i and ending at j - if i lt j then
- Swap Ai and A j
- ReverseArray(A, i 1, j - 1)
- end if
- return

Tips on Constructing Recursion

- In creating recursive methods, it is important to

define the methods in ways that facilitate

recursion. - This sometimes requires that we may define

additional parameters that are passed to the

method. - For example, we defined the array reversal method

as ReverseArray(A, i, j), not ReverseArray(A).

Implementation in Java

- public static void arrayReversal (int a)
- arrayReversalWithRange(a, 0, a.length-1)
- private static void arrayReversalWithRange
- (int a, int i, int j)
- if (i lt j)
- int temp ai
- ai aj
- aj temp
- arrayReversalWithRange(a,i1,j-1)

Calling arrayReversal

- public static void main (String args)
- int b 1,2,3,4,5,6,7
- arrayReversal(b)
- for (int i0 iltb.length i)
- System.out.println(bi " ")

Computing Powers

- The power function, p(x,n)xn, can be defined

recursively - This leads to an power function that runs in

linear time (for we make n recursive calls). - We can do better than this, however.

Recursive Squaring

- We can derive a more efficient linearly recursive

algorithm by using repeated squaring - For example,
- 24 2(4/2)2 (24/2)2 (22)2 42 16
- 25 21(4/2)2 2(24/2)2 2(22)2 2(42) 32
- 26 2(6/ 2)2 (26/2)2 (23)2 82 64
- 27 21(6/2)2 2(26/2)2 2(23)2 2(82) 128.

A Recursive Squaring Method

- Algorithm Power(x, n)
- Input A number x and integer n
- Output The value xn
- if n 0 then
- return 1
- if n is odd then
- y Power(x, (n - 1)/ 2)
- return x y y
- else
- y Power(x, n/ 2)
- return y y

Analyzing the Recursive Squaring Method

- Algorithm Power(x, n)
- Input A number x and integer n
- Output The value xn
- if n 0 then
- return 1
- if n is odd then
- y Power(x, (n - 1)/ 2)
- return x y y
- else
- y Power(x, n/2)
- return y y

Each time we make a recursive call we halve the

value of n hence, we make log n recursive calls.

That is, this method runs in O(log n) time.

It is important that we used a variable twice

here rather than calling the method twice.

Further Analysis

- Need to limit the range of n, or.
- Add the recursive condition
- if n lt 0 return 1 / Power(x, -n)

Tail Recursion 1

- Tail recursion occurs when a linearly recursive

method makes its recursive call as its last step. - The array reversal method is an example.
- Such methods can easily be converted to

non-recursive methods (which saves on some

resources), often by the compiler and runtime

system.

Tail Recursion Example

- Algorithm IterativeReverseArray(A, i, j )
- Input An array A and nonnegative integer

indices i and j - Output The reversal of the elements in A

starting at index i and ending at j - while i lt j do
- Swap Ai and A j
- i i 1
- j j - 1
- return

Tail Recursion 2

- Tips for linear recursion, write your method

using tail recursion. - Example Fac-1 does not use tail recursion.

Fac-2 does.

Binary Recursion

- Binary recursion occurs whenever there are two

recursive calls for each non-base case. - Example the DrawTicks method for drawing ticks

on an English ruler.

A Binary Recursive Method for Drawing Ticks

- // draw a tick with no label
- public static void drawOneTick(int tickLength)

drawOneTick(tickLength, - 1) - // draw one tick
- public static void drawOneTick(int tickLength,

int tickLabel) - for (int i 0 i lt tickLength i)
- System.out.print("-")
- if (tickLabel gt 0) System.out.print(" "

tickLabel) - System.out.print("\n")
- public static void drawTicks(int tickLength)

// draw ticks of given length - if (tickLength gt 0) // stop when

length drops to 0 - drawTicks(tickLength- 1) // recursively

draw left ticks - drawOneTick(tickLength) // draw center

tick - drawTicks(tickLength- 1) // recursively

draw right ticks - public static void drawRuler(int nInches, int

majorLength) // draw ruler - drawOneTick(majorLength, 0) // draw tick 0

and its label - for (int i 1 i lt nInches i)

Note the two recursive calls

Binary Recursion

- Binary Recursions are expensive.
- If possible, convert it to linear recursion.

Fibonacci Numbers

- Fibonacci numbers are defined recursively
- F0 0
- F1 1
- Fi Fi-1 Fi-2 for i gt 1.

Recursive Fibonacci Algorithm

- Algorithm BinaryFib(k)
- Input Nonnegative integer k
- Output The kth Fibonacci number Fk
- if k 1 then
- return k
- else
- return BinaryFib(k - 1) BinaryFib(k - 2)
- Binary recursion from Goodrichs book.
- Any problem here?

A C Implementation

- long fib(unsigned long n)
- if (n lt 1)
- return n
- else
- return fib(n-1)fib(n-2)

Fibonacci Number

- Negative Fibonacci Number
- F-1 1,
- F-2 -1,
- Fn F(n2)-F(n1).
- 1,-1,2,-3,5,-8,13,

Analyzing the Binary Recursion Fibonacci Algorithm

- Let nk denote number of recursive calls made by

BinaryFib(k). Then - n0 1
- n1 1
- n2 n1 n0 1 1 1 1 3
- n3 n2 n1 1 3 1 1 5
- n4 n3 n2 1 5 3 1 9
- n5 n4 n3 1 9 5 1 15
- n6 n5 n4 1 15 9 1 25
- n7 n6 n5 1 25 15 1 41
- n8 n7 n6 1 41 25 1 67.
- Note that the value at least doubles for every

other value of nk. That is, nk gt 2k/2. It is

exponential!

A Better Fibonacci Algorithm

- Use linear recursion instead
- Algorithm LinearFibonacci(k)
- Input A nonnegative integer k
- Output Pair of Fibonacci numbers (Fk,

Fk-1) - if k 1 then
- return (k, 0)
- else
- (i, j) LinearFibonacci(k - 1)
- return (i j, i)
- Runs in O(k) time.

Implementation

- Java and C do not return multiple values.
- Perls implementation
- sub fib
- return (1,0) if _0 1
- my (i, j) fib(_0-1)
- return (ij, i)
- print "fib(13) " fib(13) "\n"

Java implementation

- public static int Fab(int n)
- if (n lt 2) return 1
- return FabHelper(n,2,1,1)
- private static int FabHelper(int n, int k, int

fk, int fk_1) - if (n k) return fk
- else
- return FabHelper(n, k1, fk fk_1, fk)

Questions and Comments?