4. Elementary Sorts Flashcards

1
Q

Rules of the game.

A

Our primary concern is algorithms for rearranging arrays of items where each item contains a key. The objective is to rearrange the items such that their keys are in ascending order. In Java, the abstract notion of a key is captured in a built-in mechanism—the Comparable interface. With but a few exceptions, our sort code refers to the data only through two operations: the method less() that compares objects and the method exch() that exchanges them.
private static boolean less(Comparable v, Comparable w) {
return (v.compareTo(w) < 0);
}

private static void exch(Comparable[] a, int i, int j) {
Comparable swap = a[i];
a[i] = a[j];
a[j] = swap;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Sorting cost model.

A

When studying sorting algorithms, we count compares and exchanges. For algorithms that do not use exchanges, we count array accesses.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Extra memory.

A

The sorting algorithms we consider divide into two basic types: those that sort in place (no extra memory except perhaps for a small function-call stack or a constant number of instance variables), and those that need enough extra memory to hold another copy of the array to be sorted.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Types of data.

A

Our sort code is effective for any type of data that implements Java’s Comparable interface. This means that there is a method compareTo() for which v.compareTo(w) returns an integer that is negative, zero, or positive when v < w, v = w, or v > w, respectively. The method must implement a total order:

! Reflexive: for all v, v = v.
! Antisymmetric: for all v and w, if (v < w) then (w > v); and if (v = w) then (w = v).
! Transitive: for all v, w, and x, if (v ≤ w) and (w ≤ x), then v ≤ x.

In addition, v.compareTo(w) must throw an exception if v and w are of incompatible types or if either is null.
Date.java illustrates how to implement the Comparable interface for a user-defined type.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

//Date.java
/**
* The {@code Date} class is an immutable data type to encapsulate a
* date (day, month, and year).
* <p>
*/
public class Date implements Comparable<Date> {</Date>

A

private static final int[] DAYS = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

private final int month;   // month (between 1 and 12)
private final int day;     // day   (between 1 and DAYS[month]
private final int year;    // year

/**
* Initializes a new date from the month, day, and year.
* @param month the month (between 1 and 12)
* @param day the day (between 1 and 28-31, depending on the month)
* @param year the year
* @throws IllegalArgumentException if this date is invalid
*/
public Date(int month, int day, int year) {
if (!isValid(month, day, year)) throw new IllegalArgumentException(“Invalid date”);
this.month = month;
this.day = day;
this.year = year;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

//Date.java
/**
* Initializes new date specified as a string in form MM/DD/YYYY.
* @param date the string representation of this date
* @throws IllegalArgumentException if this date is invalid
*/
public Date(String date) {

A

String[] fields = date.split(“/”);
if (fields.length != 3) {
throw new IllegalArgumentException(“Invalid date”);
}
month = Integer.parseInt(fields[0]);
day = Integer.parseInt(fields[1]);
year = Integer.parseInt(fields[2]);
if (!isValid(month, day, year)) throw new IllegalArgumentException(“Invalid date”);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

//Date.java
/**
* Return the month.
* @return the month (an integer between 1 and 12)
*/
public int month() {

A

return month;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

//Date.java
/**
* Returns the day.
* @return the day (an integer between 1 and 31)
*/
public int day() {

A

return day;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

//Date.java
/**
* Returns the year.
* @return the year
*/
public int year() {

A

return year;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

//Date.java
// is the given date valid?
private static boolean isValid(int m, int d, int y) {

A

if (m < 1 || m > 12) return false;
if (d < 1 || d > DAYS[m]) return false;
if (m == 2 && d == 29 && !isLeapYear(y)) return false;
return true;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

//Date.java
// is y a leap year?
private static boolean isLeapYear(int y) {

A

if (y % 400 == 0) return true;
if (y % 100 == 0) return false;
return y % 4 == 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

//Date.java
/**
* Returns the next date in the calendar.
*
* @return a date that represents the next day after this day
*/
public Date next() {

A

if (isValid(month, day + 1, year)) return new Date(month, day + 1, year);
else if (isValid(month + 1, 1, year)) return new Date(month + 1, 1, year);
else return new Date(1, 1, year + 1);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

//Date.java
/**
* Compares two dates chronologically.
*
* @param that the other date
* @return {@code true} if this date is after that date; {@code false} otherwise
*/
public boolean isAfter(Date that) {

A

return compareTo(that) > 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

//Date.java
/**
* Compares two dates chronologically.
*
* @param that the other date
* @return {@code true} if this date is before that date; {@code false} otherwise
*/
public boolean isBefore(Date that) {

A

return compareTo(that) < 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

//Date.java
/**
* Compares two dates chronologically.
*
* @return the value {@code 0} if the argument date is equal to this date;
* a negative integer if this date is chronologically less than
* the argument date; and a positive integer if this date is
* chronologically after the argument date
*/
@Override
public int compareTo(Date that) {

A

if (this.year < that.year) return -1;
if (this.year > that.year) return +1;
if (this.month < that.month) return -1;
if (this.month > that.month) return +1;
if (this.day < that.day) return -1;
if (this.day > that.day) return +1;
return 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

//Date.java
/**
* Returns a string representation of this date.
*
* @return the string representation in the format MM/DD/YYYY
*/
@Override
public String toString() {

A

return month + “/” + day + “/” + year;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

/**
* Compares this date to the specified date.
*
* @param other the other date
* @return {@code true} if this date equals {@code other}; {@code false} otherwise
*/
@Override
public boolean equals(Object other) {//Date.java

A

if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
Date that = (Date) other;
return (this.month == that.month) && (this.day == that.day) && (this.year == that.year);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

//Date.java
/**
* Returns an integer hash code for this date.
*
* @return an integer hash code for this date
*/
@Override
public int hashCode() {

A

return day + 31month + 3112*year;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

//Date.java
/**
* Unit tests the {@code Date} data type.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {

A

Date today = new Date(2, 25, 2004);
StdOut.println(today);
for (int i = 0; i < 10; i++) {
today = today.next();
StdOut.println(today);
}

    StdOut.println(today.isAfter(today.next()));
    StdOut.println(today.isAfter(today));
    StdOut.println(today.next().isAfter(today));

    Date birthday = new Date(10, 16, 1971);
    StdOut.println(birthday);
    for (int i = 0; i < 10; i++) {
        birthday = birthday.next();
        StdOut.println(birthday);
    }
}

}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Selection sort.

A

One of the simplest sorting algorithms works as follows: First, find the smallest item in the array, and exchange it with the first entry. Then, find the next smallest item and exchange it with the second entry. Continue in this way until the entire array is sorted. This method is called selection sort because it works by repeatedly selecting the smallest remaining item. Selection.java is an implementation of this method.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

//Selection.java
import java.util.Comparator;

/**
* The {@code Selection} class provides static methods for sorting an
* array using <em>selection sort</em>.
* This implementation makes ~ ½ <em>n</em>2 compares to sort
* any array of length <em>n</em>, so it is not suitable for sorting large arrays.
* It performs exactly <em>n</em> exchanges.
* <p>
* This sorting algorithm is not stable. It uses Θ(1) extra memory
* (not including the input array).
* <p>
*/
public class Selection {

A

// This class should not be instantiated.
private Selection() { }

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

//Selection.java
/**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {

A

int n = a.length;
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i+1; j < n; j++) {
if (less(a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, 0, i);
}
assert isSorted(a);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

//Selection.java
/**
* Rearranges the array in ascending order, using a comparator.
* @param a the array
* @param comparator the comparator specifying the order
*/
public static void sort(Object[] a, Comparator comparator) {

A

int n = a.length;
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i+1; j < n; j++) {
if (less(comparator, a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, comparator, 0, i);
}
assert isSorted(a, comparator);
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

//Selection.java
/*
* Helper sorting functions.
*/

// is v < w ?
private static boolean less(Comparable v, Comparable w) {
A

return v.compareTo(w) < 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

//Selection.java
/*
* Helper sorting functions.
*/
// is v < w ?
private static boolean less(Comparator comparator, Object v, Object w) {

A

return comparator.compare(v, w) < 0;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

//Selection.java
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {

A

Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}

27
Q

//Selection.java
// is the array a[] sorted?
private static boolean isSorted(Comparable[] a) {

A

return isSorted(a, 0, a.length - 1);
}

28
Q

//Selection.java
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Comparable[] a, int lo, int hi) {

A

for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}

29
Q

//Selection.java
// is the array a[] sorted?
private static boolean isSorted(Object[] a, Comparator comparator) {

A

return isSorted(a, comparator, 0, a.length - 1);
}

30
Q

//Selection.java
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Object[] a, Comparator comparator, int lo, int hi) {

A

for (int i = lo + 1; i <= hi; i++)
if (less(comparator, a[i], a[i-1])) return false;
return true;
}

31
Q

//Selection.java
// print array to standard output
private static void show(Comparable[] a) {

A

for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}

32
Q

//Selection.java
/**
* Reads in a sequence of strings from standard input; selection sorts them;
* and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {

A

String[] a = StdIn.readAllStrings();
Selection.sort(a);
show(a);
}
}

33
Q

Selection sort uses ____ compares and n exchanges to sort an array of length n.

A

n^2/2

34
Q

Insertion sort.

A

The algorithm that people often use to sort bridge hands is to consider the cards one at a time, inserting each into its proper place among those already considered (keeping them sorted). In a computer implementation, we need to make space for the current item by moving larger items one position to the right, before inserting the current item into the vacated position. Insertion.java is an implementation of this method, which is called insertion sort.

35
Q

//Insertion.java
import java.util.Comparator;

/**
* The {@code Insertion} class provides static methods for sorting an
* array using insertion sort.
* <p>
* In the worst case, this implementation makes ~ ½ <em>n</em>2
* compares and ~ ½ <em>n</em>2 exchanges to sort an array
* of length <em>n</em>. So, it is not suitable for sorting large arbitrary
* arrays. More precisely, the number of exchanges is exactly equal to the
* number of inversions. So, for example, it sorts a partially-sorted array
* in linear time.
* <p>
* This sorting algorithm is stable.
* It uses Θ(1) extra memory (not including the input array).
* <p>
*/
public class Insertion {

A

// This class should not be instantiated.
private Insertion() { }

36
Q

//Insertion.java
/**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {

A

int n = a.length;
for (int i = 1; i < n; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1]); j–) {
exch(a, j, j-1);
}
assert isSorted(a, 0, i);
}
assert isSorted(a);
}

37
Q

//Insertion.java
/**
* Rearranges the subarray a[lo..hi) in ascending order, using the natural order.
* @param a the array to be sorted
* @param lo left endpoint (inclusive)
* @param hi right endpoint (exclusive)
*/
public static void sort(Comparable[] a, int lo, int hi) {

A

for (int i = lo + 1; i < hi; i++) {
for (int j = i; j > lo && less(a[j], a[j-1]); j–) {
exch(a, j, j-1);
}
}
assert isSorted(a, lo, hi);
}

38
Q

//Insertion.java
/**
* Rearranges the array in ascending order, using a comparator.
* @param a the array
* @param comparator the comparator specifying the order
*/
public static void sort(Object[] a, Comparator comparator) {

A

int n = a.length;
for (int i = 1; i < n; i++) {
for (int j = i; j > 0 && less(a[j], a[j-1], comparator); j–) {
exch(a, j, j-1);
}
assert isSorted(a, 0, i, comparator);
}
assert isSorted(a, comparator);
}

39
Q

//Insertion.java
/**
* Rearranges the subarray a[lo..hi) in ascending order, using a comparator.
* @param a the array
* @param lo left endpoint (inclusive)
* @param hi right endpoint (exclusive)
* @param comparator the comparator specifying the order
*/
public static void sort(Object[] a, int lo, int hi, Comparator comparator) {

A

for (int i = lo + 1; i < hi; i++) {
for (int j = i; j > lo && less(a[j], a[j-1], comparator); j–) {
exch(a, j, j-1);
}
}
assert isSorted(a, lo, hi, comparator);
}

40
Q

//Insertion.java
// return a permutation that gives the elements in a[] in ascending order
// do not change the original array a[]
/**
* Returns a permutation that gives the elements in the array in ascending order.
* @param a the array
* @return a permutation {@code p[]} such that {@code a[p[0]]}, {@code a[p[1]]},
* …, {@code a[p[n-1]]} are in ascending order
*/
public static int[] indexSort(Comparable[] a) {

A

int n = a.length;
int[] index = new int[n];
for (int i = 0; i < n; i++)
index[i] = i;

    for (int i = 1; i < n; i++)
        for (int j = i; j > 0 && less(a[index[j]], a[index[j-1]]); j--)
            exch(index, j, j-1);

    return index
41
Q

//Insertion.java
// is v < w ?
private static boolean less(Comparable v, Comparable w) {

A

return v.compareTo(w) < 0;
}

42
Q

//Insertion.java
// is v < w ?
private static boolean less(Object v, Object w, Comparator comparator) {

A

return comparator.compare(v, w) < 0;
}

43
Q

//Insertion.java
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {

A

Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}

44
Q

//Insertion.java
// exchange a[i] and a[j] (for indirect sort)
private static void exch(int[] a, int i, int j) {

A

int swap = a[i];
a[i] = a[j];
a[j] = swap;
}

45
Q

//Insertion.java
/* Check if array is sorted - useful for debugging.
*/
private static boolean isSorted(Object[] a, Comparator comparator) {

A

return isSorted(a, 0, a.length, comparator);
}

46
Q

//Insertion.java
// is the array a[lo..hi) sorted
private static boolean isSorted(Object[] a, int lo, int hi, Comparator comparator) {

A

for (int i = lo + 1; i < hi; i++)
if (less(a[i], a[i-1], comparator)) return false;
return true;
}

47
Q

///Insertion.java
/ print array to standard output
private static void show(Comparable[] a) {

A

for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}

48
Q

//Insertion.java
/**
* Reads in a sequence of strings from standard input; insertion sorts them;
* and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {

A

String[] a = StdIn.readAllStrings();
Insertion.sort(a);
show(a);
}
}

49
Q

//Insertion.java
For randomly ordered arrays of length N with with distinct keys, insertion sort uses _______ compares and _____ exchanges on the average. The worst case is _____compares and ___ exchanges and the best case is ____compares and 0 exchanges.

A

For randomly ordered arrays of length N with with distinct keys, insertion sort uses ~N2/4 compares and ~N2/4 exchanges on the average. The worst case is ~ N2/2 compares and ~ N2/2 exchanges and the best case is N-1 compares and 0 exchanges.

50
Q

The number of exchanges used by insertion sort is equal to the

A

number of inversions in the array, and the number of compares is at least equal to the number of inversions and at most equal to the number of inversions plus the array size.

51
Q

For randomly ordered arrays of distinct values, the running times of insertion sort and selection sort are

A

quadratic and within a small constant factor of one another.

52
Q

Shellsort

A

Shellsort is a simple extension of insertion sort that gains speed by allowing exchanges of entries that are far apart, to produce partially sorted arrays that can be efficiently sorted, eventually by insertion sort. The idea is to rearrange the array to give it the property that taking every hth entry (starting anywhere) yields a sorted sequence. Such an array is said to be h-sorted.
By h-sorting for some large values of h, we can move entries in the array long distances and thus make it easier to h-sort for smaller values of h. Using such a procedure for any increment sequence of values of h that ends in 1 will produce a sorted array: that is shellsort. Shell.java is an implementation of this method.

53
Q

//Shell.java
/**
* The {@code Shell} class provides static methods for sorting an
* array using <em>Shellsort</em> with
* <a> Knuth’s increment sequence</a>
* (1, 4, 13, 40, …). In the worst case, this implementation makes
* Θ(<em>n</em>3/2) compares and exchanges to sort
* an array of length <em>n</em>.
* <p>
* This sorting algorithm is not stable.
* It uses Θ(1) extra memory (not including the input array).
* <p>
*/
public class Shell {

A

// This class should not be instantiated.
private Shell() { }

54
Q

//Shell.java
/**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {

A

int n = a.length;

    // 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, ...
    int h = 1;
    while (h < n/3) h = 3*h + 1;

    while (h >= 1) {
        // h-sort the array
        for (int i = h; i < n; i++) {
            for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) {
                exch(a, j, j-h);
            }
        }
        assert isHsorted(a, h);
        h /= 3;
    }
    assert isSorted(a);
}
55
Q

//Shell.java
// is v < w ?
private static boolean less(Comparable v, Comparable w) {

A

return v.compareTo(w) < 0;
}

56
Q

//Shell.java
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {

A

Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}

57
Q

//Shell.java
/*
* Check if array is sorted - useful for debugging.
*/
private static boolean isSorted(Comparable[] a) {

A

for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}

58
Q

//Shell.java
// is the array h-sorted?
private static boolean isHsorted(Comparable[] a, int h) {

A

for (int i = h; i < a.length; i++)
if (less(a[i], a[i-h])) return false;
return true;
}

59
Q

//Shell.java
// print array to standard output
private static void show(Comparable[] a) {

A

for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}

60
Q

//Shell.java
/**
* Reads in a sequence of strings from standard input; Shellsorts them;
* and prints them to standard output in ascending order.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {

A

String[] a = StdIn.readAllStrings();
Shell.sort(a);
show(a);
}

}

61
Q

The number of compares used by shellsort with the increments 1, 4, 13, 40, 121, 364, …

A

s bounded by a small multiple of N times the number of increments used.

62
Q

The number of compares used by shellsort with the increments 1, 4, 13, 40, 121, 364, … is

A

O(N3/2).

63
Q

The compiler gives a warning when I compile Insertion.java. Is ther any way to avoid this?

Insertion.java:73: warning: [unchecked] unchecked call to compareTo(T)
as a member of the raw type java.lang.Comparable
return (v.compareTo(w) < 0);

A

Yes, if you use static generics, as in InsertionPedantic.java. It leads to awkward (but warning-free) code.