recursion1. 2 what kind of problem is “recursive”? same recursive problems are those problems...

27
Recursion 1 Recursion

Upload: nelson-lane

Post on 27-Dec-2015

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 1

Recursion

Page 2: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 2

Recursion

What kind of problem is “recursive”?

Recursive problems are those problems where in order to solve the original problem you have to solve one or more identical but smaller

version(s) of the samesame problem.

Examples:

• Binary Search

• Finding nth Fibonacci number

• Finding Factorials

• Finding exponents

• TOH

• Finding your way out of maze

• 8-queens problem

• Graph traversal problems

• …

i.e.,

To solve problem of “size n”, first solve the same problem of “size n-1 or less”.

How are each of these

recursive problems?

Page 3: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 3

Recursion

First understanding a method and method call:

For a method, the method call defines the problem size:

… method(int k){ //method implementation //solves problem of size k}

Solve a problem of “size n” - method(n)

Solve a problem of “size n-1” - method(n-1)

Solve a problem of “size n/2” - method(n/2)

Solve a problem of “size 1” - method(1)

Implicit sizes

Solve a problem over an arrayof n elements

- method(int[] array, int left, int right);

Page 4: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 4

xn/2 * xn/2, if n is evenxn/2 * xn/2 * x, if n is odd

Recursive problems and methods:Problem: Find the exponent xn

FirstFirst solve xn-1

To find: xn

xn = xn-1 * x1

… x2 = x1 * x1

x1 = x0 * x1

x0 = 1

Recursive solution 1: Recursive solution 2:

xn =

Recursive problems are those problems where in order to solve the original problem you have to solve one or more identical but smaller

version(s) of the problem until you reach the trivial or base case.

To find: xn FirstFirst solve xn/2

… x2 = x1 * x1

x1 = x0 * x0 * x1

x0 = 1Trivial orbase case

Page 5: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 5

Recursive problems and methods:

Problem:

Corresponding method signature:

Find the exponent xn

/** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n*/public static double power(double x, int n)

Usage:

Solve 5^3 - power(5,3);

Solve 0.031^9 - power(0.031,9);

Solve 10472834^0 - power(10472834,0);

Solve x^n - power(x,n)

Solve x^(n-1) - power(x,n-1)

Page 6: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 6

Recursive problems and methods:

Connecting the problem and the code

xn = xn-1 * x1

The problem The method signature

/** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n*/public static double power(double x, int n)

Solve xn = power(x,n) = power(x,n-1) * x

+

Page 7: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 7

Recursive problems and methods:

Problem: Corresponding method:

Find the exponent xn

Recursive solution:

/** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n*/public static double power(double x, int n)

Solve x^(n-1)

Solve x^n

xn = xn-1 * x1

… x1 = x0 * x1

x2 = x1 * x1

x0 = 1

{ if (n == 0) return 1;

Base case always first!

Recursion next

double ans = power(x,n-1) * x;return ans;

}

Page 8: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 8

Recursive problems and methods:

Trace the following call:

… System.out.println(power(5,4));...

Page 9: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 9

Recursive problems and methods:

Problem: Corresponding method:

Find the exponent xn

Recursive solution:

/** * purpose of this method is to calculate x^n * @param x - the base * @param n - the exponent, n >= 0 * @return x^n*/public static double power(double x, int n)

double xn;double xno2 = power(x,n/2);if (n%2 == 0) xn = xno2 * xno2;else xn = xno2 * xno2 *x;

return xn;}

Solve xn/2

Solve x^n

{ if (n == 0) return 1;

xn/2 * xn/2, if n is evenxn/2 * xn/2 * x, if n is odd

xn =

… x2 = x1 * x1

x1 = x0 * x0 * x1

x0 = 1

Page 10: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 10

Recursion - Can you do this?

Find x! as follows: 0! = 1 x! = x*(x-1)!

/** * purpose of this method is to calculate n! * @param n - the value whose factorial we have to find * @return n!*/public static double factorial(int n)

Page 11: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 11

Recursion - another example:Problem:

f(n) = 1, when n is 0 or 1

f(n) = f(n-1) + f(n-2) when n > 1

Base case

Recursive case

/*** Finds the nth Fibonacci number* @param n - the index of the Fibonacci number to find, n >= 0* @return nth Fibonacci number*/

public static int fibonacci(int n){ if ((n==0) || (n==1)) return 1;

//apparently, n is not 0 or 1 return fibonacci(n-1) + fibonacci(n-2);}

Trace the following:

System.out.println(fibonacci(4));

Page 12: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 12

Recursion:

Inherent cost of recursion:

A lot of system overhead associated with method calls

Advantages of recursion:

Provides a clear readable intuitive solution to the problem.

Page 13: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 13

How to problem solve recursively

Given a problem of size n ask the following question:

“ASSUMING I knew the solution to a smaller but identical sub problem,can I use that answer to solve my current problem?”

If “yes”, how do you proceed?

1. Imagine m() to be a method that will solve all such smaller problems.

2. Imagine calling m() and incorporate the solution from m() to solve current problem. [Think carefully about the signature of m().]

3. What size is the smallest sub problems? (Note: smallest sub problem cannot be broken apart because if it could that would imply a still smaller problem!)

4. All such small sub problems found in 3 are your base cases.

5. Replace all m()‘s with a call to your self.

6. Put all the pieces together.

Page 14: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 14

How to problem solve recursively

Problem: Write a method to find xn

Can this problem be solved recursively?

“ASSUMING I knew the solution …

1. Imagine a method m() that will solve this problem, and call it

m(x,n-1) -> returns an int, xn-1

2. Imagine calling m() and incorporating that solution to solve …

int x_to_n = x * m(x, n-1)

3. What size is the smallest sub problems?

n = 0, x0 = 1

4. All such small sub problems found in 3 are your base cases.

if (n == 0) return 1;

5. Replace all m()‘s with a call to your self.

int x_to_n = x * power(x,n-1);

Page 15: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 15

How to problem solve recursively

6. Put all the pieces together.

public static int power(int x, int n){ if (n == 0) return 1;

//apparently, n is not zero int x_to_n = x * power(x,n-1); return x_to_n;}

Page 16: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 16

The (classic) Towers of Hanoi problem

Objective:

To move n rings from any peg start peg (s) to any destination peg (d), without

1. moving more than one ring at a time, and 2. without placing a larger ring on top of a smaller ring.

Analysis/algorithm:

?

peg 1 peg 2 peg 3

Is it recursive?

What would method m() look like?

Can we phrase the solution in terms of m()?

s = 1, d = 3

Page 17: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 17

Towers of Hanoi problem

/** * The purpose of this method is to solve the towers of Hanoi * problem for n rings being moved amongst 3 pegs, numbered 1,2 * and 3. * @param n - the number of rings to move * @param o - the origination peg (where the rings currently are) * @param d - where the rings should be moved too */

public static void toh(int n, int o, int d){ //check for base if (n == 1) System.out.println(“move a ring from “+o+” to “+d); else{ toh(n-1,o, 6-o-d); System.out.println(“move a ring from “+o+” to “+d); toh(n-1, 6-o-d, d); }}

Page 18: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 18

Towers of Hanoi problem

TOH(3,1,3)

TOH(2,1,2)

TOH(1,1,3) TOH(1,3,2)

TOH(2,2,3)

TOH(1,2,1) TOH(1,1,3)

Trace: toh(3,1,3)

What is the performance of toh()?

Page 19: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 19

Recursion and arrays - print an array out, backwards

Problem: print an array backwards.

Can this problem be solved recursively?

1. Imagine a method m() that will solve this problem. [Think carefully about the signature of such a method.]

2. Imagine calling m() and incorporating that solution to solve …

3. What size is the smallest sub problems?

4. All such small sub problems found in 3 are your base cases.

5. Replace all m()‘s with a call to your self. [What happens if the signatures don’t match?]

6. Put all the pieces together.Performance?

Page 20: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 20

Searching an array

Problem: Search and array, A, of integers for a value B. If found return location index; otherwise return –1.

Performance?

Page 21: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 21

Recursion - Divide and Conquer - Binary search

/** * This method searches an array of sorted Comparable objects * @param a - the array of sorted Comparable objects * @val - the value searched for * @l - the left starting index * @r - the right starting index * @return array index of value if found; -1 otherwise. */public static int binarySearch(int[] a, int val, int l, int r){

if (l > r) return -1; //not found int mid = (l+r)/2; if (val == a[mid]) return mid; //found if (val < a[mid]) return binarySearch(a,val,l,mid-1); else return binarySearch(a,val,mid+1,r);}

Performance?

Page 22: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 22

Sorting an array

Problem: Sort an integer array, A. What recursive strategies can we use, if any? Can you come up with any?

Page 23: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 23

Recursion - Divide and Conquer - Merge Sort

/** This method will sort an array using merge sort*/public static int[] sort(int a[]){

return mergeSort(a, l, r);}

/** This method will sort an array of Comparable objects * using Merge sort * @param array - the array to sort * @param l - the left index * @param r - the right index */public static void mergeSort(int[] array, int l, int r){ if (l < r){ int mid = (l+r)/2; //divide in half mergeSort(array, l, mid); //sort each half mergeSort(array, mid+1, r); merge(array, l,mid,r); //merge sorted halves }}

public static void merge(int[] array, int l, int mid, int r){ 1. create a temp array to hold the merging halves 2. merge the two halves 3. Make sure all elements of the two halves are in the temp array 4. Copy elements from the temp array back to array.} Performance?

Page 24: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 24

Recursion - Divide and Conquer - Merge Sort

public static void merge(int[] array, int l, int mid, int r){

//create an array int[] temp = new int[r+1];

//merge int li=l, ri = mid+1, ti = l-1; while ((li <= mid) && (ri <= r)){ ti++; if (array[li] < array[ri]){ temp[ti] = array[li]; li++; } else{ temp[ti] = array[ri]; ri++; } }

// Make sure all elements of the two halves are in the temp array for(int i=li; i<=mid; i++, ti++) temp[ti] = array[i]; for(int i=ri; i<=r; i++, ti++) temp[ti] = array[i];

//Copy elements from the temp array back to array. for(int i=l; i<=r; i++) array[i] = temp[i];}

Page 25: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 25

Recursion - Divide and Conquer - Quick Sort

Problem: Sort an integer array, A. public static int[] sort(int[] a)

Can this problem be solved recursively?

Imagine 1:Move elements in array into the left and right of the array such that all the elements on the left are less than some pivot value and all the elements to the right are greater. Imagine that you know this break even index.

Imagine 2:Imagine that m() is a method that will sort an array’s elements between l and r:

int[] m(int[] a, int l, int r)

2. Imagine calling m() and incorporating that solution to solve …

int pivIndex = partition(a, l,r);m(a,l,pivIndex-1);m(a,pivIndex+1, r);

3. Base case(s)

if (l < r) {

Page 26: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 26

Recursion - Divide and Conquer - Quick Sort

/** This method will sort an array using quick sort*/public static int[] sort(int a[]){

return quiskSort(a, l, r);}

/** This method will sort an array of Comparable objects * using Quick sort * @param array - the array to sort * @param l - the left index * @param r - the right index */private static void quickSort(int[] array, int l, int r){ if (l < r){ int pivot = partition(array,l,r); quickSort(array, l, pivot-1); //sort each half quickSort(array, pivot+1, r); }}

private static void partition(int[] array, int l,int r){ 0. Pivot value is array[l] 1. Scan from left to right and right to left moving items larger than pivot to the right and those smaller than pivot to the left 2. Move pivot to its sorted position 3. return pivot index}

Performance?

Page 27: Recursion1. 2 What kind of problem is “recursive”? same Recursive problems are those problems where in order to solve the original problem you have to

Recursion 27

Recursion - Divide and Conquer - Quick Sort

public static void partition(int[] array, int l,int r){ //Pivot value is array[l] int pivotVal = array[l];

//Scan from left to right and right to left moving items larger //than pivot to the right and those smaller than pivot to the left int li = l, ri = r; while (li < ri){ while ((pivotVal > array[li]) && (li<ri)) li++; while (pivotVal < array[ri]) ri--; if (li<ri){ int temp = array[li]; array[li] = array[ri]; array[ri] = temp; li++; ri--; } }

//Move pivot to its sorted position array[l] = array[ri]; array[ri] = pivotVal;

//return pivot index return ri;}