introduction to recursion by dr. bun yue professor of computer science [email protected] 2013...

37
Introduction to Recursion by Dr. Bun Yue Professor of Computer Science [email protected] http://sce.uhcl.edu/yue/ 2013 CSCI 3333 Data Structures

Upload: loraine-morrison

Post on 28-Dec-2015

237 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Introduction to Recursion

by

Dr. Bun YueProfessor of Computer Science

[email protected]://sce.uhcl.edu/yue/

2013

CSCI 3333 Data Structures

Page 2: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Acknowledgement

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

Page 3: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 4: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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).

Page 5: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Mathematical Induction

Proof by Induction is recursive in nature.

To prove S(n) for all n = 1, 2, 3. Show:

1. S(n) is true for n = 1.2. If S(k) is true for all k from 1 to n-1,

then S(n) is true

Page 6: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Recursive Methods

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

Recursive definition:

elsenfn

nnf

)1(

0 if1)(

Page 7: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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?

Page 8: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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?

Page 9: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 10: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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

Page 11: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Tips on Recursive Analysis

Identify exit and recursive conditions.

Ensure that the conditions cover all input ranges.

Page 12: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 13: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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) = dT(N) = T(N-1) + cSolving by substitution: T(N) = cN + d

= O(N)

Page 14: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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 thenSwap A[i] and A[ j]ReverseArray(A, i + 1, j - 1)

end if; return;

Page 15: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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).

Page 16: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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 < j){ int temp = a[i];

a[i] = a[j];a[j] = temp;arrayReversalWithRange(a,i+1,j-1);

}}

Page 17: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Calling arrayReversal

public static void main (String args[]) {

int b[] = {1,2,3,4,5,6,7}; arrayReversal(b); for (int i=0; i<b.length; i++) { System.out.println(b[i] + " "); }

}

Page 18: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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

Page 19: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

even is 0 if

odd is 0 if

0 if

)2/,(

)2/)1(,(

1

),(2

2

x

x

x

nxp

nxpxnxp

Page 20: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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

Page 21: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 22: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Further Analysis

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

if n < 0 return 1 / Power(x, -n);

Page 23: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 24: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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

Page 25: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Tail Recursion 2

Tips: for linear recursion, write your method using tail recursion.

Example: Fac-1 does not use tail recursion. Fac-2 does.

Page 26: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 27: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

A Binary Recursive Method for Drawing Ticks

// draw a tick with no labelpublic static void drawOneTick(int tickLength) { drawOneTick(tickLength, - 1); }

// draw one tickpublic static void drawOneTick(int tickLength, int tickLabel) { for (int i = 0; i < tickLength; i++) System.out.print("-"); if (tickLabel >= 0) System.out.print(" " + tickLabel); System.out.print("\n");}public static void drawTicks(int tickLength) { // draw ticks of given length if (tickLength > 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 <= nInches; i++) { drawTicks(majorLength- 1); // draw ticks for this inch drawOneTick(majorLength, i); // draw tick i and its label }}

Note the two recursive calls

Page 28: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Binary Recursion

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

recursion.

Page 29: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Fibonacci Numbers

Fibonacci numbers are defined recursively:

F0 = 0

F1 = 1

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

Page 30: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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 Goodrich’s book. Any problem here?

Page 31: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

A C++ Implementation

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

Page 32: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Fibonacci Number

Negative Fibonacci Number: F-1 = 1,

F-2 = -1,

Fn = F(n+2)−F(n+1).

1,-1,2,-3,5,-8,13,…

Page 33: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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!

Page 34: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

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.

Page 35: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Implementation

Java and C++ do not return multiple values.

Perl’s implementation:

sub fib {return (1,0) if $_[0] == 1;my ($i, $j) = fib($_[0]-1);return ($i+$j, $i);

}

print "fib(13): " + fib(13) + "\n";

Page 36: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Java implementation

public static int Fab(int n) {if (n <= 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, k+1, fk + fk_1, fk);

}

Page 37: Introduction to Recursion by Dr. Bun Yue Professor of Computer Science yue@uhcl.edu  2013 yue@uhcl.edu

Questions and Comments?