introduction to recursion csci 3333 data structures

Post on 12-Jan-2016

263 Views

Category:

Documents

10 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Introduction to Recursion

CSCI 3333 Data Structures

Acknowledgement

Dr. Bun Yue Mr. Charles Moen Dr. Wei Ding Ms. Krishani Abeysekera Dr. Michael Goodrich Dr. Behrouz A. Forouzan Dr. Richard F. Gilberg

Recursion

Recursion is defining a function that calls itself as a subroutine.

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 x+1 is

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

Recursive Methods

A recursive method may calls itself.Example: factorial.Iterative definition:n! = n . (n-1) . (n-2) … 3 . 2 . 1

Recursive definition:

elsenfn

nnf

)1(

0 if1)(

Recursive Factorial Algorithm

//By Forouzan

Factorial Implementation: Fac-1

Found here in C++:

int factorial(int number) { int temp;

if (number <= 1) return 1; temp = number * factorial(number - 1); return temp;

}

What do you think?

Another Implementation: Fac-2

int recursiveFactorial(int n) { if (n == 0)

return 1; // base case else

return n * recursiveFactorial(n- 1);

// recursive case /general case }

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 call must reduce the size of the problem and move it toward the base case; reduces the size of the problem. .

Visualizing Recursion

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

Example recursion trace:

recursiveFactorial (4)

recursiveFactorial (3)

recursiveFactorial (2)

recursiveFactorial (1)

recursiveFactorial (0)

return 1

call

call

call

call

return 1*1 = 1

return 2*1 = 2

return 3*2 = 6

return 4*6 = 24 final answercall

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.

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 < j then

Swap A[i] and A[ j]ReverseArray(A, i + 1, j - 1)

return

Tips on Constructing Recursion

In creating recursive methods, it is important to define the methods in ways that facilitate recursion.

This sometimes requires 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).

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.

else)1,(

0 if1),(

nxpx

nnxp

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 = 1625 = 21+(4/2)2 = 2(24/2)2 = 2(22)2 = 2(42) = 3226 = 2(6/ 2)2 = (26/2)2 = (23)2 = 82 = 6427 = 21+(6/2)2 = 2(26/2)2 = 2(23)2 = 2(82) = 128.

Note: This definition leads to linear recursive algorithm that uses O(n)

even is 0 if

odd is 0 if

0 if

)2/,(

)2/)1(,(

1

),(2

2

x

x

x

nxp

nxpxnxp

A Recursive Squaring Method

Algorithm Power(x, n): Input: A number x and integer n Output: The value xn

if n = 0 thenreturn 1

if n is odd theny = Power(x, (n - 1)/ 2)return x · y · y

elsey = 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 thenreturn 1

if n is odd theny = Power(x, (n - 1)/ 2)return x · y · y

elsey = Power(x, n/ 2)return y · y It is important that we

used a variable twice here rather than calling the method twice.

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.

Further Analysis

Need to limit the range of n, or. Add the recursive condition:

if n < 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 be easily 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 < j do

Swap A[i ] and A[ j ]i = i + 1j = 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. Also known as Higher-Order Recursion. Example: Fibonacci number

0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Fibonacci Numbers

Fibonacci numbers are defined recursively:

F0 = 0

F1 = 1

Fi = Fi-1 + Fi-2 for i > 1.

Binary Recursion

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

recursion.

Recursive Fibonacci Algorithm

Algorithm BinaryFib(k): Input: Nonnegative integer k

Output: The kth Fibonacci number Fk

if k = 1 thenreturn k

elsereturn BinaryFib(k - 1) + BinaryFib(k - 2)

Binary recursion from the text book. Any problem here?

A C++ Implementation

long fib(unsigned long n) { if (n <= 1) { return n; } else { return fib(n-1)+fib(n-2); }}

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 > 2k/2. It is exponential!

Analyzing the Binary Recursion Fibonacci Algorithm

//By Forouzan

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.

Questions and Comments?

top related