1. Given the code below, answer the succeeding questions.
public static void insertionSort(Comparable[] A) {
int k, j;
Comparable tmp;
int N = A.length;
for (k = 1; k < N, k++) {
tmp = A[k];
j = k - 1;
while ((j > = 0) && (A[j].compareTo(tmp) > 0)) {
A[j+1] = A[j]; // move one value over one place to the right
j--;
}
A[j+1] = tmp; // insert kth value in correct place relative to previous
// values
}
}
a. What is the running time for insertion when:
(1) the array is already sorted in ascending order?
(2) the array is already sorted in descending order?
b. One each iteration of its outer loop, insertion sort finds the correct place to insert the next
item, relative to the ones that are already in sorted order. It does this by searching back
through those items, one at a time. Would insertion sort be speeded up if instead it used binary
search to find the correct place to insert the next item?
(a) When the array is already sorted, the inner loop in the insertion sort code never executes, so the
time is O(N).
(b) When the array is in reverse sorted order, the inner loop executes the maximum possible number of
times, so the running time is as bad as possible (and is O(N2)).
Using binary search to find the right place to insert the next item would (usually) speed up the sort (as
we saw in the film Sorting out Sorting), but would not change the complexity, which would still be O(N2)
in the worst case, since in the worst case (when the item needs to be inserted at the very beginning of
the array each time) it is necessary to move O(N2) values.
2. Fill in the missing code in the mergeSort method.
public static void mergeSort(Comparable[] A) {
mergeAux(A, 0, A.length - 1); // call the aux. function to do all the work
}
private static void mergeAux(Comparable[] A, int low, int high)
{
// base case
if (low == high) return;
// recursive case
// Step 1: Find the middle of the array (conceptually, divide it in half)
int mid = (low + high) / 2;
// Steps 2 and 3: Sort the 2 halves of A
mergeAux(A, low, mid);
mergeAux(A, mid+1, high);
// Step 4: Merge sorted halves into an auxiliary array
Comparable[] tmp = new Comparable[high-low+1];
int left = low; // index into left half
int right = mid+1; // index into right half
int pos = 0; // index into tmp
while ((left <= mid) && (right <= high)) {
// choose the smaller of the two values "pointed to" by left, right
// copy that value into tmp[pos]
// increment either left or right as appropriate
// increment pos
...
}
// here when one of the two sorted halves has "run out" of values, but
// there are still some in the other half; copy all the remaining values
// to tmp
// Note: only 1 of the next 2 loops will actually execute
while (left <= mid) { ... }
while (right <= high) { ... }
// all values are in tmp; copy them back into A
arraycopy(tmp, 0, A, low, tmp.length);
}
while ((left <= mid) && (right <= high)) {
// choose the smaller of the two values "pointed to" by left, right
// copy that value into tmp[pos]
// increment either left or right as appropriate
// increment pos
if (A[left].compareTo(A[right] < 0) {
tmp[pos] = A[left];
left++;
}
else {
tmp[pos] = A[right];
right++;
pos++;
// here when one of the two sorted halves has "run out" of values, but
// there are still some in the other half; copy all the remaining values
// to tmp
// Note: only 1 of the next 2 loops will actually execute
while (left <= mid) {
A[pos] = A[left];
left++;
pos++;
while (right <= high) {
A[pos] = A[right];
right++;
pos++;