Download Building Java Programs

Document related concepts
no text concepts found
Transcript
Building Java Programs
Chapter 13:
Searching and Sorting
Copyright 2006 by Pearson Education
1
Chapter outline

Searching and sorting in the Java class libraries





Program efficiency



sequential and binary search
sorting
shuffling
custom ordering with Comparators
algorithm analysis
complexity classes and Big-Oh notation
Implementing searching and sorting algorithms



binary search
selection sort
merge sort
Copyright 2006 by Pearson Education
2
Searching and sorting in
the Java class libraries
reading: 13.1
Copyright 2006 by Pearson Education
3
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 ...
Copyright 2006 by Pearson Education
4
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.
Copyright 2006 by Pearson Education
5
Binary search example
Copyright 2006 by Pearson Education
6
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.
Copyright 2006 by Pearson Education
7
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
Copyright 2006 by Pearson Education
8
Sorting in the class libraries

Java provides two sorting methods:

Arrays.sort (for an array)
// demonstrate the Arrays.sort method
String[] 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)
Copyright 2006 by Pearson Education
9
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
Copyright 2006 by Pearson Education
10
Custom ordering with
Comparators
reading: 13.1
Copyright 2006 by Pearson Education
11
Custom ordering

Sometimes, the default ordering is not what you want.

Example: The following code sorts the strings in a casesensitive 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.
Copyright 2006 by Pearson Education
12
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
0
>0
if o1 comes before o2,
if o1 and o2 are equivalent,
if o1 comes after o2.
Copyright 2006 by Pearson Education
13
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());
}
}
Copyright 2006 by Pearson Education
14
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]
Copyright 2006 by Pearson Education
15
Program efficiency
reading: 13.2
Copyright 2006 by Pearson Education
16
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.
Copyright 2006 by Pearson Education
17
Rules for algorithm analysis



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.
Copyright 2006 by Pearson Education
18
More examples


Larger statements can also occur sequentially, in which
case their runtimes are added.
If larger statements are nested, their runtimes are
multiplied.
Copyright 2006 by Pearson Education
19
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
Copyright 2006 by Pearson Education
20
Growth rate example
Consider these graphs of functions.
Perhaps each one represents an algorithm:
n3 + 2n2
100n2 + 1000
• Which grows
faster?
Copyright 2006 by Pearson Education
21
Growth rate example
• How about now?
Copyright 2006 by Pearson Education
22
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 array
public 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;
}
Copyright 2006 by Pearson Education
23
Runtime of range 1

Observation: runtime seems to roughly quadruple when
input size is doubled
Copyright 2006 by Pearson Education
24
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;
}
Copyright 2006 by Pearson Education
25
Runtime of range 2

Observation: about twice as fast; same growth pattern

(runtime quadruples when input size is doubled)
Copyright 2006 by Pearson Education
26
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;
}
Copyright 2006 by Pearson Education
27
Runtime of range 3
Much faster than others

Runtime doubles when
input size doubles

Copyright 2006 by Pearson Education
28
Complexity classes and
Big-oh notation
reading: 13.2
Copyright 2006 by Pearson Education
29
Big-Oh notation

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.
Copyright 2006 by Pearson Education
30
Hierarchy of Big-Oh

Complexity classes in increasing order of growth:









constant time
logarithmic
linear
loglinear
quadratic
cubic
...
exponential
...
O(1)
O(log N)
O(N)
O(N log N)
O(N2)
O(N3)
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.
Copyright 2006 by Pearson Education
31
Program loop runtimes
for (int i = 0; i < N; i += c)
<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)
<statements>;

// O(N)
// O(log N)
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)
<statements>;

// O(N2)
The loop maximum is N2, so the runtime is quadratic.

Loop executes its body exactly (N2 / c) times.
Copyright 2006 by Pearson Education
32
More loop runtimes

Nesting loops multiplies their runtimes.
for (int i = 0; i < N; i += c) {
for (int j = 0; j < N; i += c) {
<statements>;
}
}

// O(N2)
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) {
<statements>;
}
for (int i = 0; i < N; i += c) {
for (int j = 0; j < N; i *= c) {
<statements>;
}
}
Copyright 2006 by Pearson Education
// O(N)
// O(N log N)
33
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++;
}
Copyright 2006 by Pearson Education
34
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++;
}
}
Copyright 2006 by Pearson Education
35
Implementing binary
search
reading: 13.3
Copyright 2006 by Pearson Education
36
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.
Copyright 2006 by Pearson Education
37
Binary search example
searching for value 16
0
4
1
7
2
16
3
20
4
37
5
38
6
43
Copyright 2006 by Pearson Education
min
mid (too big!)
max
38
Binary search example
searching for value 16
0
4
min
1
7
mid (too small!)
2
16
3
20
4
37
5
38
6
43
Copyright 2006 by Pearson Education
max
39
Binary search example
searching for value 16
0
4
1
7
2
16
3
20
4
37
5
38
6
43
Copyright 2006 by Pearson Education
min, mid, max (found it!)
40
Binary search pseudocode
binary 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.
Copyright 2006 by Pearson Education
41
Binary search code

The following code implements binary search:
// Returns an
// appears in
// pre: array
public static
int min =
int max =
index at which the target
the given input array, or -1 if not found.
is sorted.
int binarySearch(int[] numbers, int target) {
0;
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
}
Copyright 2006 by Pearson Education
42
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
Copyright 2006 by Pearson Education
43
Implementing selection
sort
reading: 13.3
Copyright 2006 by Pearson Education
44
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
Copyright 2006 by Pearson Education
45
Selection sort example
Copyright 2006 by Pearson Education
46
Selection sort example 2
Index
Value
1st pass
2nd pass
3rd pass
0
1
2
3
4
5
6
7
27
63
1
72
64
58
14
9
1
63
27
72
64
58
14
9
1
9
27
72
64
58
14
63
1
9
14
72
64
58
27
63
…
Copyright 2006 by Pearson Education
47
Selection sort code

The following code implements selection sort:
// places elements of the given array into sorted order
public 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;
}
Copyright 2006 by Pearson Education
48
Selection sort runtime

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)
Copyright 2006 by Pearson Education
49
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.
Copyright 2006 by Pearson Education
50
Implementing merge sort
reading: 13.4
Copyright 2006 by Pearson Education
51
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.
Copyright 2006 by Pearson Education
52
Merge sort example
98 23 45 14
98 23 45 14
98 23
98
45 14
23
45
23 98
14 45
14 23 45 98
6
14
6
67 33 42
6
67 33 42
6
67
6
6
6
67
67
33 42
33
42
33 42
33 42 67
14 23 33 42 45 67 98
Copyright 2006 by Pearson Education
53
Merge sort example 2
13
6
21
18
9
4
8
20
0
7
13
6
21
0
18
9
3
4
4
8
20
7
13
6
21
18
9
4
8
20
0
1
2
3
4
5
6
7
13
6
21
18
9
4
8
20
0
1
2
3
4
5
6
7
6
13
18
21
4
9
8
20
0
1
2
3
4
5
6
7
18
21
4
8
3
4
6
13
0
4
6
0
Copyright 2006 by Pearson Education
8
9
13
9
20
7
18
20
21
7
54
Merging two sorted arrays

merge operation:

Given two sorted arrays, merge operation produces a sorted
array with all the elements of the two arrays
A
6
C

13
4
18
6
21
8
9
B
4
8
9
13
18
20
21
20
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.
Copyright 2006 by Pearson Education
55
Merge operation example
Copyright 2006 by Pearson Education
56
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;
}
Copyright 2006 by Pearson Education
57
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++;
}
}
}
Copyright 2006 by Pearson Education
58
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);
}
}
Copyright 2006 by Pearson Education
59
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.
Copyright 2006 by Pearson Education
60