60
1 Copyright 2006 by Pearson Education Building Java Building Java Programs Programs Chapter 13: Searching and Sorting

Copyright 2006 by Pearson Education 1 Building Java Programs Chapter 13: Searching and Sorting

  • View
    216

  • Download
    0

Embed Size (px)

Citation preview

1Copyright 2006 by Pearson Education

Building Java Building Java ProgramsPrograms

Chapter 13: Searching and Sorting

2Copyright 2006 by Pearson Education

Chapter outline Searching and sorting in the Java class libraries

sequential and binary search sorting shuffling custom ordering with Comparators

Program efficiency algorithm analysis complexity classes and Big-Oh notation

Implementing searching and sorting algorithms binary search selection sort merge sort

3Copyright 2006 by Pearson Education

Searching and sorting Searching and sorting in the Java class in the Java class

librarieslibrariesreading: 13.1

4Copyright 2006 by Pearson Education

Sequential search Imagine searching for a particular word in an ArrayList

of words from a book:int index = words.indexOf(word);if (index >= 0) { System.out.println(word + " is word #" + index);} else { System.out.println(word + " is not found.");}

sequential search: One that examines each element of a list in sequence until it finds the target value or reaches the end of the list.

The indexOf method above uses a sequential search.

index 0 1 2 3 4 5 6 ...

value It was

the

best

of times

it ...

5Copyright 2006 by Pearson Education

Binary search algorithm binary search: An algorithm that searches for a value

in a sorted list by repeatedly eliminating half the list from consideration.

Can be written iteratively or recursively implemented in Java as method Arrays.binarySearch in java.util package

Algorithm pseudocode (searching for a value K): Start out with the search area being from indexes 0 to length-1. Examine the element in the middle of the search area.

If it is K, stop. Otherwise,

If it is smaller than K, eliminate the upper half of the search area. If it is larger than K, eliminate the lower half of the search area. Repeat the above examination.

6Copyright 2006 by Pearson Education

Binary search example

7Copyright 2006 by Pearson Education

Using binarySearch Java provides two binary search methods:

Arrays.binarySearch (for an array)

// binary search on an array:int[] numbers = {-3, 2, 8, 12, 17, 29, 44, 58, 79};int index = Arrays.binarySearch(numbers, 29);System.out.println("29 is found at index " + index);

Collections.binarySearch (for a List)

// binary search on ArrayList with the same values:int index = Collections.binarySearch(list, 29);System.out.println("29 is found at index " + index);

Note that the values in the array / list are in sorted order. If they are not, binarySearch is not guaranteed to work

properly.

8Copyright 2006 by Pearson Education

Sorting sorting: Rearranging the values in a list into a given

order (often into their natural ascending order). One of the fundamental problems in computer science Many sorts are comparison-based (must determine order

through comparison operations on the input data)

<, >, compareTo, …

index 0 1 2 3 4 5 6 7

value 15 2 8 1 17 10 12 5

index 0 1 2 3 4 5 6 7

value 1 2 5 8 10 12 15 17

9Copyright 2006 by Pearson Education

Sorting in the class libraries Java provides two sorting methods:

Arrays.sort (for an array)// demonstrate the Arrays.sort methodString[] strings = {"c", "b", "g", "h", "d", "f", "e", "a"};System.out.println(Arrays.toString(strings));Arrays.sort(strings);System.out.println(Arrays.toString(strings));

Output:[c, b, g, h, d, f, e, a][a, b, c, d, e, f, g, h]

Collections.sort (for a List)

10Copyright 2006 by Pearson Education

Shuffling shuffling: Rearranging the elements of a list into a random order.

Java has a shuffle method for a List, Collections.shuffle:

String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};ArrayList<String> deck = new ArrayList<String>();for (String rank : ranks) { // build sorted deck for (String suit : suits) { deck.add(rank + " of " + suit); }}Collections.shuffle(deck);System.out.println("Top card = " + deck.get(0));

Output (for one example run):Top card = 10 of Spades

11Copyright 2006 by Pearson Education

Custom ordering with Custom ordering with ComparatorsComparators

reading: 13.1

12Copyright 2006 by Pearson Education

Custom ordering Sometimes, the default ordering is not what you want.

Example: The following code sorts the strings in a case-sensitive order, so the uppercase letters come first.We may have wanted a case-insensitive ordering instead.

String[] strings = {"Foxtrot", "alpha", "echo", "golf", "bravo", "hotel", "Charlie", "DELTA"};Arrays.sort(strings);System.out.println(Arrays.toString(strings));

Output:[Charlie, DELTA, Foxtrot, alpha, bravo, echo, golf, hotel]

You can describe a custom sort ordering by creating a class called a comparator.

13Copyright 2006 by Pearson Education

Comparators The Comparator interface in java.util describes a

method for comparing two objects of a given type:public interface Comparator<T> { public int compare(T o1, T o2);}

Note that Comparator is a generic interface. T will be replaced by the type of object you are actually comparing.

The compare method's job is to decide the relative ordering of the two given objects and return an appropriate integer:

< 0 if o1 comes before o2, 0 if o1 and o2 are equivalent, > 0 if o1 comes after o2.

14Copyright 2006 by Pearson Education

Comparator example The following Comparator compares Strings, ignoring case:

public class CaseInsensitiveComparator implements Comparator<String> {

public int compare(String s1, String s2) { return s1.toLowerCase().compareTo( s2.toLowerCase()); }}

15Copyright 2006 by Pearson Education

Sorting with Comparators The sorting methods shown previously can also be

called with a Comparator as a second parameter. The sorting algorithm will use that comparator to order the

elements of the array or list.

String[] strings = {"Foxtrot", "alpha", "echo", "golf", "bravo", "hotel", "Charlie", "DELTA"};Arrays.sort(strings, new CaseInsensitiveComparator());System.out.println(Arrays.toString(strings));[Charlie, DELTA, Foxtrot, alpha, bravo, echo, golf, hotel]

Output:[alpha, bravo, Charlie, DELTA, echo, Foxtrot, golf, hotel]

16Copyright 2006 by Pearson Education

Program efficiencyProgram efficiency

reading: 13.2

17Copyright 2006 by Pearson Education

Efficiency efficiency: A measure of the computing resources used

by a program, such as time, memory, or disk space.

time efficiency: How quickly a program runs "Fast enough" is often relative to the task being performed.

5 minutes to render a complex 3D scene for a movie is fast. 5 minutes to search Google is slow.

Ways to measure the efficiency of a program: empirical analysis: Program the algorithm, run it, and time it. algorithm analysis: Applying techniques to mathematically

estimate the algorithm's runtime without actually coding it.

18Copyright 2006 by Pearson Education

Most individual statements take 1 unit of time to run. When multiple statements are executed sequentially,

their runtimes are added.

When statements are executed in a loop, the runtime is multiplied by the number of repetitions of the loop.

Rules for algorithm analysis

19Copyright 2006 by Pearson Education

More examples Larger statements can also occur sequentially, in which

case their runtimes are added. If larger statements are nested, their runtimes are

multiplied.

20Copyright 2006 by Pearson Education

Relative rates of growth most algorithms' runtime can be expressed as a

function of the input size N

rate of growth: measure of how quickly the graph of a function rises

goal: distinguish between fast- and slow-growing functions

we only care about very large input sizes(for small sizes, most any algorithm is fast enough)

this helps us discover which algorithms will run more quickly or slowly, for large input sizes

21Copyright 2006 by Pearson Education

Growth rate exampleConsider these graphs of functions.Perhaps each one represents an algorithm:n3 + 2n2

100n2 + 1000

• Which growsfaster?

22Copyright 2006 by Pearson Education

Growth rate example• How about now?

23Copyright 2006 by Pearson Education

Range algorithm 1 Let's examine the efficiency and growth rate of three

algorithms for finding the range (difference between largest and smallest element) in an array.

First algorithm (looks at all pairs of values to find which pair is the largest and smallest): // returns the range of numbers in the given arraypublic static int range(int[] numbers) { int maxDiff = 0; for (int i = 0; i < numbers.length; i++) { for (int j = 0; j < numbers.length; j++) { int diff = Math.abs(numbers[j] - numbers[i]); maxDiff = Math.max(maxDiff, diff); } } return maxDiff;}

24Copyright 2006 by Pearson Education

Runtime of range 1

Observation: runtime seems to roughly quadruple when input size is doubled

25Copyright 2006 by Pearson Education

Range algorithm 2 The first algorithm redundantly makes each comparison

twice (when i <= j, when i > j).

Second, improved algorithm: public static int range2(int[] numbers) { int maxDiff = 0; for (int i = 0; i < numbers.length; i++) { for (int j = i + 1; j < numbers.length; j++) { int diff = Math.abs(numbers[j] - numbers[i]); maxDiff = Math.max(maxDiff, diff); } } return maxDiff;}

26Copyright 2006 by Pearson Education

Observation: about twice as fast; same growth pattern (runtime quadruples when input size is doubled)

Runtime of range 2

27Copyright 2006 by Pearson Education

Range algorithm 3 We can discover the largest and smallest values in a

single pass over the array, rather than using many nested passes over all values.

Third algorithm: public static int range3(int[] numbers) { int max = numbers[0]; int min = max; for (int i = 1; i < numbers.length; i++) { if (numbers[i] > max) { max = numbers[i]; } else if (numbers[i] < min) { min = numbers[i]; } } return max - min;}

28Copyright 2006 by Pearson Education

Runtime of range 3

Much faster than others

Runtime doubles when input size doubles

29Copyright 2006 by Pearson Education

Complexity classes Complexity classes and Big-oh notationand Big-oh notation

reading: 13.2

30Copyright 2006 by Pearson Education

complexity class: Category of algorithms' runtime based on relationship to input size.

Determined by the exponent of the most frequently executed line of code in the algorithm.

big-Oh notation: A shorthand for describing complexity classes.

Example: If the most frequently executed line of an algorithm runs approximately N3 times, we say the algorithm is "order N3" or O(N3) for short.

We are concerned with how the function grows when N is large. We are not picky about constant factors.

Big-Oh notation

31Copyright 2006 by Pearson Education

Hierarchy of Big-Oh Complexity classes in increasing order of growth:

constant time O(1) logarithmic O(log N) linear O(N) loglinear O(N log N) quadratic O(N2) cubic O(N3)

... exponential O(2N) ...

An algorithm from a lower complexity class will run much faster than one from a higher complexity class when the value of N becomes very large.

32Copyright 2006 by Pearson Education

for (int i = 0; i < N; i += c) // O(N) <statements>;

Adding to the loop counter means that the loop runtime grows linearly when compared to its maximum value N.

Loop executes its body exactly N / c times.

for (int i = 0; i < N; i *= c) // O(log N) <statements>;

Multiplying the loop counter means that the maximum value N must grow exponentially to linearly increase the loop runtime; therefore, it is logarithmic.

Loop executes its body exactly logc N times.

for (int i = 0; i < N * N; i += c) // O(N2) <statements>;

The loop maximum is N2, so the runtime is quadratic. Loop executes its body exactly (N2 / c) times.

Program loop runtimes

33Copyright 2006 by Pearson Education

Nesting loops multiplies their runtimes.for (int i = 0; i < N; i += c) { // O(N2) for (int j = 0; j < N; i += c) { <statements>; }}

Loops in sequence add together their runtimes, which means the loop set with the larger runtime dominates.for (int i = 0; i < N; i += c) { // O(N) <statements>;}for (int i = 0; i < N; i += c) { // O(N log N) for (int j = 0; j < N; i *= c) { <statements>; }}

More loop runtimes

34Copyright 2006 by Pearson Education

Loop runtime problems Approximate the value of the variable sum after the

following code fragment, as an expression in terms of input size n. Use Big-Oh notation to describe the algorithm's overall runtime.int sum = 0;for (int i = 1; i <= N; i *= 2) { sum++;} for (int i = 1; i <= 1000; i++) { sum++; sum++;}

35Copyright 2006 by Pearson Education

Loop runtime problems Approximate the value of the variable sum after the

following code fragment, as an expression in terms of input size n. Use Big-Oh notation to describe the algorithm's overall runtime.int sum = 0;for (int i = 1; i <= N; i++) { for (int j = 1; j <= i / 2; j += 2) { sum++; }}

36Copyright 2006 by Pearson Education

Implementing binary Implementing binary searchsearch

reading: 13.3

37Copyright 2006 by Pearson Education

Recall: binary search binary search: An algorithm that searches for a value

in a sorted list by repeatedly eliminating half the list from consideration.

Can be written iteratively or recursively

Algorithm pseudocode (searching for a value K): Start out with the search area being from indexes 0 to length-1. Examine the element in the middle of the search area.

If it is K, stop. Otherwise,

If it is smaller than K, eliminate the upper half of the search area. If it is larger than K, eliminate the lower half of the search area. Repeat the above examination.

38Copyright 2006 by Pearson Education

4

7

16

20

37

38

43

0

1

2

3

4

5

6

min

mid (too big!)

max

searching for value 16

Binary search example

39Copyright 2006 by Pearson Education

4

7

16

20

37

38

43

0

1

2

3

4

5

6

min

mid (too small!)

max

searching for value 16

Binary search example

40Copyright 2006 by Pearson Education

4

7

16

20

37

38

43

0

1

2

3

4

5

6

min, mid, max (found it!)

searching for value 16

Binary search example

41Copyright 2006 by Pearson Education

Binary search pseudocodebinary search array a for value i: if all elements have been searched, result is -1. examine middle element a[mid]. if a[mid] equals i, result is mid. if a[mid] is greater than i, binary search lower half of a for i. if a[mid] is less than i, binary search upper half of a for i.

42Copyright 2006 by Pearson Education

Binary search code The following code implements binary search:

// Returns an index at which the target// appears in the given input array, or -1 if not found.// pre: array is sorted.public static int binarySearch(int[] numbers, int target) { int min = 0; int max = numbers.length - 1;

while (min <= max) { int mid = (max + min) / 2; if (numbers[mid] == target) { return mid; // found it! } else if (numbers[mid] < target) { min = mid + 1; // too small } else { // numbers[mid] > target max = mid - 1; // too large } }

return -1; // not found}

43Copyright 2006 by Pearson Education

Runtime of binary search How do we analyze the runtime of binary search?

The algorithm's runtime is dominated by a while loop. Each pass of that loop cuts the search space in half.

How many times does this division in half take place? 2repetitions N repetitions log2N

44Copyright 2006 by Pearson Education

Implementing Implementing selection sortselection sort

reading: 13.3

45Copyright 2006 by Pearson Education

Selection sort selection sort: orders a list of values by repetitively

putting a particular value into its final position

more specifically: find the smallest value in the list switch it with the value in the first position find the next smallest value in the list switch it with the value in the second position repeat until all values are in their proper places

46Copyright 2006 by Pearson Education

Selection sort example

47Copyright 2006 by Pearson Education

Index0 1 2 3 4 5 6 7

Value27 63 1 72 64 58 14 9

1st pass1 63 27 72 64 58 14 9

2nd pass1 9 27 72 64 58 14 63

3rd pass1 9 14 72 64 58 27 63

Selection sort example 2

48Copyright 2006 by Pearson Education

Selection sort code The following code implements selection sort:

// places elements of the given array into sorted orderpublic static void selectionSort(int[] a) { for (int i = 0; i < a.length - 1; i++) { // find index of smallest element int smallest = i; for (int j = i + 1; j < a.length; j++) { if (a[j] < a[smallest]) { smallest = j; } }

swap(a, i, smallest); // swap smallest to front }}

public static void swap(int[] list, int i, int j) { int temp = list[i]; list[i] = list[j]; list[j] = temp;}

49Copyright 2006 by Pearson Education

Observation: runtime roughly quadruples when input size is doubled

makes sense because the code performs two nested loops over the array of size N

its runtime should be O(N2)

Selection sort runtime

50Copyright 2006 by Pearson Education

Sorting practice problem Consider the following array of int values:

[22, 11, 34, -5, 3, 40, 9, 16, 6]

Perform the selection sort algorithm on this data.Write the contents of the array after each pass of the outermost loop of selection sort until the array is sorted.

51Copyright 2006 by Pearson Education

Implementing merge Implementing merge sortsort

reading: 13.4

52Copyright 2006 by Pearson Education

Merge sort merge sort: orders a list of values by recursively

dividing the list in half until each sub-list has one element, then recombining

Invented by John von Neumann in 1945 relies on observation that if you have two sorted lists of values,

they can be combined into a single larger sorted list quickly

merge sort pseudocode: split the array into two halves. merge sort the left half (recursively). merge sort the right half (recursively). combine the two halves into a sorted whole.

53Copyright 2006 by Pearson Education

674523 14 6 3398 42

4523 1498 676 33 42

45 142398

2398 45 14

676 33 42

676 33 42

23 98 4514 676 4233

14 23 45 98 6 33 42 67

6 14 23 33 42 45 67 98

Merge sort example

54Copyright 2006 by Pearson Education

13 6 21 18 9 4 8 20

0 7

4 6 8 9 13 18 20 21

0 7

13 6 21 18

0 3

9 4 8 20

4 7

6 13 18 21

0 3

4 8 9 20

4 7

13 6

0 1

21 18

2 3

9 4

4 5

8 20

6 7

6 13

0 1

18 21

2 3

4 9

4 5

8 20

6 7

13

0

6

1

21

2

18

3

9

4

4

5

8

6

20

7

Merge sort example 2

55Copyright 2006 by Pearson Education

merge operation: Given two sorted arrays, merge operation produces a sorted

array with all the elements of the two arrays

A 6 13 18 21 B 4 8 9 20

C 4 6 8 9 13 18 20 21

Running time of merge : O(N), where N is the number of elements in the merged array.

When merging two sorted parts of the same array, we'll need a temporary array to store the merged whole.

Merging two sorted arrays

56Copyright 2006 by Pearson Education

Merge operation example

57Copyright 2006 by Pearson Education

Split into halves code The following code splits an array into its two halves:

// Returns the first half of the given array.public static int[] leftHalf(int[] array) { int size1 = array.length / 2; int[] left = new int[size1]; for (int i = 0; i < size1; i++) { left[i] = array[i]; } return left;}

// Returns the second half of the given array.public static int[] rightHalf(int[] array) { int size1 = array.length / 2; int size2 = array.length - size1; int[] right = new int[size2]; for (int i = 0; i < size2; i++) { right[i] = array[i + size1]; } return right;}

58Copyright 2006 by Pearson Education

Merge code The following code implements the merge operation

// pre : result is empty; left/right are sorted// post: result contains merged sorted lists.public static void merge(int[] result, int[] left, int[] right) { int i1 = 0; // index into left array int i2 = 0; // index into right array for (int i = 0; i < result.length; i++) { if (i2 >= right.length || (i1 < left.length && left[i1] <= right[i2])) { result[i] = left[i1]; // take from left i1++; } else { result[i] = right[i2]; // take from right i2++; } }}

59Copyright 2006 by Pearson Education

Merge sort code The following code implements the overall merge sort:

// Places elements of given array into sorted order// using the merge sort algorithm.public static void mergeSort(int[] array) { if (array.length > 1) { // split array into two halves int[] left = leftHalf(array); int[] right = rightHalf(array);

// recursively sort the two halves mergeSort(left); mergeSort(right);

// merge the sorted halves into a sorted whole merge(array, left, right); }}

60Copyright 2006 by Pearson Education

Sorting practice problem Consider the following array of int values.

[22, 11, 34, -5, 3, 40, 9, 16, 6]

Perform the merge sort algorithm on this data.Write the contents of the array after each of the recursive calls of merge sort have finished.