- Sections 14.4-14.5, Special Topic 14.1, 14.2

I put up videos for all CS46B lectures (ok, almost all—once there was a technical problem).

Do you care?

- Videos? What videos? I never looked at one.
- They are terrible. I'd only watch them if I had a sleep disorder.
- Maybe mildly helpful, but if they weren't there, I probably wouldn't miss them.
- Those are great—keep it up.

- Sorts an array by
- Cutting the array in half
- Recursively sorting each half
- Merging the sorted halves

- Dramatically faster than the selection sort

- Divide an array in half and sort each half

- Merge the two sorted arrays into a single sorted array

```
public void sort()
{
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
. . .
MergeSorter firstSorter = new MergeSorter(first);
MergeSorter secondSorter = new MergeSorter(second);
firstSorter.sort(); secondSorter.sort(); merge(first, second);
}
```

Look at the first `while`

loop of the `merge`

method. Which of the following is true when the loop is complete?

- All elements of
`first`

have been added to`a`

- All elements of
`second`

have been added to`a`

- All elements of
`first`

or`second`

have been added to`a`

- Both
`first`

and`second`

contain some elements that haven't been added to`a`

Consider the `merge`

method, and assume that `a`

has *n* elements. What is the big-Oh efficiency of the merge method?

- O(1)
- O(n)
- O(n log n)
- O(n
^{2})

n | Merge Sort (milliseconds) | Selection Sort (milliseconds) |
---|---|---|

10,000 | 40 | 786 |

20,000 | 73 | 2,148 |

30,000 | 134 | 4,796 |

40,000 | 170 | 9,192 |

50,000 | 192 | 13,321 |

60,000 | 205 | 19,299 |

- In an array of size
*n*, count how many times an array element is visited - Assume
*n*is a power of 2:*n*= 2^{m} - Calculate the number of visits to create the two sub-arrays and then merge the two sorted arrays
- 3 visits to merge each element or 3
*n*visits - 2
*n*visits to create the two sub-arrays - total of 5
*n*visits

- 3 visits to merge each element or 3

- Let
*T*(*n*) denote the number of visits to sort an array of*n*elements then- T(
*n*) = T(*n*/2) + T(*n*/2) + 5*n*or - T(
*n*) = 2T(*n*/2) + 5*n*

- T(
- The visits for an array of size
*n*/2 is: T(*n*/2) = 2T(*n*/4) + 5*n*/2- So T(
*n*) = 2 × 2T(*n*/4) +5*n*+ 5*n*

- So T(
- The visits for an array of size
*n*/4 is: T(*n*/4) = 2T(*n*/8) + 5*n*/4- So T(
*n*) = 2 × 2 × 2T(*n*/8) + 5*n*+ 5*n*+ 5*n*

- So T(

- Repeating the process
*k*times: T(*n*) = 2^{k}T(*n*/2^{k}) +5*nk* - Since
*n*= 2^{m}, when*k*=*m:*T(*n*) = 2^{m}T(*n*/2^{m}) +5*nm* - T(
*n*) =*n*T(1) +5*nm* - T(
*n*) =*n*+ 5*n*log_{2}(*n*)

- To establish growth order
- Drop the lower-order term
*n* - Drop the constant factor 5
- Drop the base of the logarithm since all logarithms are related by a constant factor
- We are left with
*n*log(*n*)

- Drop the lower-order term
- Using big-Oh notation: number of visits is O(
*n*log(*n*))

- Selection sort is an O(
*n*^{2}) algorithm - Merge sort is an O(
*n*log(*n*)) algorithm - The
*n*log(*n*) function grows much more slowly than*n*^{2}

- With selection sort and merge sort, the longer array takes 1000 times as long as with the original array.
- With selection sort and merge sort, the longer array takes 1,000,000 times as long as with the original array.
- With selection sort, the longer array takes 1,000,000 times as long, but with merge sort, it takes about the same time as with the original array
- With selection sort, the longer array takes 1,000,000 times as long, but with merge sort, it takes about 10,000 the same time as with the original array

- Divide and conquer
- Partition the range
- Split the range in two
- Everything to the left is smaller than anything to the right

- Sort each partition

- Partition the range

public void sort(int from, int to) { if (from >= to) return; int p = partition(from, to); sort(from, p); sort(p + 1, to); }

private int partition(int from, int to) { int pivot = a[from]; int i = from - 1; int j = to + 1; while (i < j) { i++; while (a[i] < pivot) i++; j--; while (a[j] > pivot) j--; if (i < j) swap(i, j); } return j; }

What happens if the array is already sorted?

- The quicksort method exits immediately
- There are O(n
^{2}) swaps - The running time is O(n
^{2}) - The running time is O(n log(n))

That's bad. A better approach is to choose the “median of three” as the pivot: that is, the middle element from `a[from]`

, `a[to]`

, and `a[(from + to)/2]`

.

Fix this program to use that strategy.

Which of the following is true?

- One needs to change the initial value of
`from`

since`a[from]`

is no longer the pivot - One needs to add a variable
`k`

that starts at`(from + to) / 2`

- One needs to change the loop condition to
`while (i <= j)`

since the pivot can now be in the middle - none of the above