recursion a recursive computation solves a problem by using the solution of the same problem with...

37
Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Upload: allyson-hall

Post on 28-Dec-2015

227 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Recursion

• A recursive computation solves a problem by using the solution of the same problem with simpler values

• The same computation occurs repeatedly

Page 2: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Example - Fibonacci Sequence

• Fibonacci sequence is a sequence of numbers defined by– 1. Basis:

• f(1)=1, f(2)=1 (two initial conditions)

– 2. Induction:• f(n)=f(n-1)+f(n-2) for n=3,4... (recursive equation)

• First ten terms– 1, 1, 2, 3, 5, 8, 13, 21, 34, 55

Page 3: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

A tester program used to generate and print Fibonacci numbers

Note that the method fib(int n) calls itself recursively

01: import java.util.Scanner;02: 03: /**04: This program computes Fibonacci numbers using a recursive05: method.06: */ 07: public class FibTester08: { 09: public static void main(String[] args)10: { 11: Scanner in = new Scanner(System.in);12: System.out.print("Enter n: ");13: int n = in.nextInt();14: 15: for (int i = 1; i <= n; i++)16: {17: long f = fib(i);18: System.out.println("fib(" + i + ") = " + f);19: }20: }21: 22: /**23: Computes a Fibonacci number.24: @param n an integer25: @return the nth Fibonacci number26: */27: public static long fib(int n)28: { 29: if (n <= 2) return 1;30: else return fib(n - 1) + fib(n - 2);31: }32: } 

Page 4: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Recursion

• For recursion to terminate, there must be special cases for the simplest inputs.– To complete our example, we must handle n <= 2

• If (n <= 2) return 1;

• Two key requirements for recursion success: – Every recursive call must simplify the computation in

some way (Recursive Step)– There must be special cases to handle the simplest

computations directly (Basis Step)

Page 5: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Sorting and Searching

• Goals– To study several sorting and searching algorithms– To appreciate that algorithms for the same task can differ

widely in performance– To understand the big-Oh notation– To learn how to estimate and compare the performance of

algorithms– To learn how to measure the running time of a program

Page 6: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Bubble Sort

• Compares each pair of adjacent items and swaps them if they are in the wrong order

• Repeated until no swaps are needed• Smaller elements "bubble" to the top of the list

Page 7: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

// Sort an array's values into ascending order.import java.awt.*;import javax.swing.*; public class BubbleSort extends JFrame {  public BubbleSort() { JTextArea outputArea = new JTextArea(); Container container = getContentPane(); container.add( outputArea ); int array[] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; String output = "Data items in original order\n";

// append original array values to String output for ( int counter = 0; counter < array.length; counter++ ) output += " " + array[ counter ]; bubbleSort( array ); // sort array output += "\n\nData items in ascending order\n";

// append sorted\ array values to String output for ( int counter = 0; counter < array.length; counter++ ) output += " " + array[ counter ]; outputArea.setText( output ); setSize( 375, 200 ); setVisible( true );  }

Page 8: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

// sort elements of array with bubble sort public void bubbleSort( int array2[] ) { // loop to control number of passes for ( int pass = 1; pass < array2.length; pass++ ) { // loop to control number of comparisons for ( int element = 0; element < array2.length - 1;

element++ ) { // compare side-by-side elements and swap them if

// first element is greater than second element if ( array2[ element ] > array2[ element + 1 ] ) swap( array2, element, element + 1 ); } } } // swap two elements of an array public void swap( int array3[], int first, int second ) { int hold; // temporary holding area for swap hold = array3[ first ]; array3[ first ] = array3[ second ]; array3[ second ] = hold; } public static void main( String args[] ) { BubbleSort application = new BubbleSort (); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }} // end class BubbleSort

Page 9: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Insertion Sort

• Insertion sort is the method that many people use to sort playing cards. Pick up one card at a time and insert it so that the cards stay sorted.Example:

Page 10: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

import java.util.Arrays;

public class InsertionSorter{ /** Sorts an array, using insertion sort. @param a the array to sort */ public static void sort(int[] a) { for (int i = 1; i < a.length; i++) { int next = a[i]; // Move all larger elements up int j = i; while (j > 0 && a[j - 1] > next) { a[j] = a[j - 1]; j--; } // Insert the element a[j] = next; } } public static void main(String[] args){

int array[] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; System.out.println("Array before sorting:" + Arrays.toString(array)); InsertionSorter.sort(array); System.out.println("Array after sorting:" + Arrays.toString(array));

}}

Page 11: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Selection Sort

• In selection sort, pick the smallest element and swap it with the first one. Pick the smallest element of the remaining ones and swap it with the next one, and so on.Example:

Page 12: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

public class SelectionSortTester { public static void main(String[] args) { int[] a = ArrayUtil.randomIntArray(20, 100); ArrayUtil.print(a); SelectionSorter sorter = new SelectionSorter(a); sorter.sort(); ArrayUtil.print(a); }} public class SelectionSorter{ public SelectionSorter(int[] anArray) { a = anArray; } public void sort() { for (int i = 0; i < a.length - 1; i++) { int minPos = minimumPosition(i); swap(minPos, i); } } //Finds the smallest element in a tail range of the array. private int minimumPosition(int from) { int minPos = from; for (int i = from + 1; i < a.length; i++) if (a[i] < a[minPos]) minPos = i; return minPos; } private void swap(int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } private int[] a;}

Page 13: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

• What really matters in comparing the complexity of algorithms?– We only care about the behaviour for large problems– Even bad algorithms can be used to solve small problems

• Big-O notation

Time Complexity

13

Page 14: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Big O notation characterizes functions according to their growth ratesf(x) is O(g(x)):

Excludes coefficients and lower order terms

Example: f(n) = 3n²+2n+1 is O(n²).

Big-O Notation

14

Page 15: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Complexity of the algorithms

• All the previous algorithms have worst time complexity (number of steps of computation) O(n2) where n is the number of numbers to sort

• Better (faster) algorithms?– E.g., Merge Sort

Page 16: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Merge Sort

• Sorts an array by– Cutting the array in half

– Recursively sorting each half

– Merging the sorted halves

Example:

Merge

Page 17: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

/** The sort method of this class sorts an array, using the merge sort algorithm.*/public class MergeSorter{ /** Sorts an array, using merge sort. */ public static void sort(int[] a) { if (a.length <= 1) { return; } int[] first = new int[a.length / 2]; int[] second = new int[a.length - first.length]; // Copy the first half of a into first, the second half into second for (int i = 0; i < first.length; i++) { first[i] = a[i]; } for (int i = 0; i < second.length; i++) { second[i] = a[first.length + i]; } sort(first); sort(second); merge(first, second, a); }

Page 18: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

/** Merges two sorted arrays into an array */ private static void merge(int[] first, int[] second, int[] a) { int iFirst = 0; // Next element to consider in the first array int iSecond = 0; // Next element to consider in the second array int j = 0; // Next open position in a

// As long as neither iFirst nor iSecond is past the end, move // the smaller element into a while (iFirst < first.length && iSecond < second.length) { if (first[iFirst] < second[iSecond]) { a[j] = first[iFirst]; iFirst++; } else { a[j] = second[iSecond]; iSecond++; } j++; }

Page 19: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

// Note that only one of the two loops below copies entries // Copy any remaining entries of the first array while (iFirst < first.length) { a[j] = first[iFirst]; iFirst++; j++; } // Copy any remaining entries of the second half while (iSecond < second.length) { a[j] = second[iSecond]; iSecond++; j++; } }}

Page 20: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

import java.util.Arrays;

public class MergeSortTester{ public static void main(String[] args) { int[] a = ArrayUtil.randomIntArray(20, 100); System.out.println(Arrays.toString(a));

MergeSorter.sort(a);

System.out.println(Arrays.toString(a)); }}

Page 21: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Merge Sort vs. Selection Sort

• Selection sort is an O(n2) algorithm• Merge sort is an O(nlog(n)) algorithm• The nlog(n) function grows much more slowly

than n2

Page 22: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Sorting in a Java Program

• The Arrays class implements a sorting method• To sort an array of integers

int[] a = . . . ;

Arrays.sort(a);

• That sort method uses the Quicksort algorithm– Quicksort

1. Divide and conquer Partition the range

2. Sort each partition

Page 23: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

import java.util.Arrays; public class BuiltInSort{ public static void main(String[] args){ String[] alphas = {"zulu", "yankee", "x-ray", "whisky", "victor", "uniform", "tango", "sierra"}; System.out.print("Initial : "); System.out.println(Arrays.toString(alphas)); Arrays.sort(alphas); // true refers to printing after each pass System.out.print("Final : "); System.out.println(Arrays.toString(alphas)); }}

Page 24: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Searching

• Linear search: also called sequential search• Examines all values in an array until it finds a

match or reaches the end• Number of visits for a linear search of an array of n elements: – The average search visits n/2 elements– The maximum visits is n

• A linear search locates a value in an array in O(n) steps

Page 25: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

01: /**02: A class for executing linear searches through an array.03: */04: public class LinearSearcher05: { 06: /**07: Constructs the LinearSearcher.08: @param anArray an array of integers09: */10: public LinearSearcher(int[] anArray)11: {12: a = anArray;13: }14: 15: /**16: Finds a value in an array, using the linear search 17: algorithm.18: @param v the value to search19: @return the index at which the value occurs, or -120: if it does not occur in the array21: */22: public int search(int v)23: { 24: for (int i = 0; i < a.length; i++)25: { 26: if (a[i] == v)27: return i;28: }29: return -1;30: }31: 32: private int[] a;33: }

Page 26: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

01: import java.util.Scanner;02: 03: /**04: This program tests the linear search algorithm.05: */06: public class LinearSearchTester07: { 08: public static void main(String[] args)09: { 10: // Construct random array11: 12: int[] a = ArrayUtil.randomIntArray(20, 100);13: ArrayUtil.print(a);14: LinearSearcher searcher = new LinearSearcher(a);15: 16: Scanner in = new Scanner(System.in);17: 18: boolean done = false;19: while (!done)20: {21: System.out.print("Enter number to search for, -1 to quit: ");22: int n = in.nextInt();23: if (n == -1) 24: done = true;25: else26: {27: int pos = searcher.search(n);28: System.out.println("Found in position " + pos);29: }30: }31: }32: }

Page 27: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Binary Search

• Locates a value in a sorted array by – Determining whether the value occurs in the first or second half– Then repeating the search in one of the halvesExample: Searching for 15 in this array

No match

Page 28: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

01: /**02: A class for executing binary searches through an array.03: */04: public class BinarySearcher05: { 06: /**07: Constructs a BinarySearcher.08: @param anArray a sorted array of integers09: */10: public BinarySearcher(int[] anArray)11: {12: a = anArray;13: }14:

Page 29: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

15: /**16: Finds a value in a sorted array, using the binary17: search algorithm.18: @param v the value to search19: @return the index at which the value occurs, or -120: if it does not occur in the array21: */22: public int search(int v)23: { 24: int low = 0;25: int high = a.length - 1;26: while (low <= high)27: {28: int mid = (low + high) / 2;29: int diff = a[mid] - v;30: 31: if (diff == 0) // a[mid] == v32: return mid;33: else if (diff < 0) // a[mid] < v 34: low = mid + 1;35: else36: high = mid - 1; 37: }38: return -1;39: }40: 41: private int[] a;42: }43:

Page 30: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Sort Objects

• Sort by one attribute

• Sort objects in java– Arrays.sort(a) ?

Page 31: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

import java.awt.*;import javax.swing.*;import java.awt.event.*;  public class ObjectsSort extends JApplet implements ActionListener{ JTextArea outputArea; JLabel l1, l2; JTextField t1, t2; JButton b1, b2; Student s, array[]; int stCount=0;  public void init() { outputArea = new JTextArea(10,15); l1=new JLabel("Enter student name"); l2=new JLabel("Enter student’s mark"); t1= new JTextField(10); t2= new JTextField(10); JPanel p1=new JPanel(); b1= new JButton("Enter student data"); b2= new JButton("Display students"); array = new Student [100]; Container container = getContentPane(); b1.addActionListener(this); b2.addActionListener(this); 

Page 32: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

p1.setLayout(new GridLayout( 3, 2 ) ); p1.add(l1); p1.add(t1); p1.add(l2); p1.add(t2); p1.add(b1); p1.add(b2); container.add( p1, BorderLayout.NORTH); container.add( new JScrollPane(outputArea), BorderLayout.CENTER ); } public void actionPerformed(ActionEvent e){ String s1="", s2="";  if (e.getSource()==b1){ s1=t1.getText(); s2=t2.getText(); int mark= Integer.parseInt(s2); array[stCount++] = new Student (s1, mark); t1.setText(""); t2.setText(""); } else if (e.getSource()==b2) { String output = "Student records with marks in descending order:\n"; bubbleSort( array ); // sort array // append sorted array values to String output for ( int counter = 0; counter < stCount; counter++ ) output +=array[counter].toString(); outputArea.setText( output ); } }

Page 33: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

// sort elements of array with marks in descending order public void bubbleSort( Student array2[] ) { // loop to control number of passes for ( int pass = 1; pass < stCount; pass++ ) { // loop to control number of comparisons for ( int element = 0; element < stCount - 1; element++ ) { // compare side-by-side elements and swap them if first

// element is greater than second element if ( array2[ element ].getMark() < array2[ element +

1 ].getMark() ) swap( array2, element, element + 1 ); } } } // swap two elements of an array.. we swap references only public void swap( Student array3[], int first, int second ) { Student hold; // temporary holding reference for swap hold = array3[ first ]; array3[ first ] = array3[ second ]; array3[ second ] = hold; }} // end of class

Page 34: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

class Student { private String name; private int mark; public Student (String n, int m){ name=n; mark=m; } public int getMark() { return mark; } public String getName() { return name; } public String toString() { return name + " has " + mark + "\n"; }}

Page 35: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Sorting with names?

• Use if (array2[ element ].getName().compareTo(array2[ element + 1 ].getName()) > 0 )

Page 36: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

The Comparable Interface

• Several classes in Java (e.g. String and Date) implement Comparable

• You can implement Comparable interface for your own classes public class Student implements Comparable{ public int compareTo(Object otherStudent) {

// TODO Auto-generated method stubStudent other = (Student) otherStudent;if (mark < other.getMark()) return -1;if (mark > other.getMark()) return 1;return 0;

} . . . }

Page 37: Recursion A recursive computation solves a problem by using the solution of the same problem with simpler values The same computation occurs repeatedly

Sorting with Comparables

• Once your class implements Comparable, simply use the Arrays.sort method:

Student students[] = new Student[3];// add students

Arrays.sort(students);

• Sort partial array– sort(Object[] a, int fromIndex, int toIndex)– fromIndex - the index of the first element (inclusive) to be

sorted– toIndex - the index of the last element (exclusive) to be

sorted