# Comparison Sorts Study Guide

**Selection sort**. One way to sort is by selection: repeatedly identifying the most extreme element and moving it to the end of the unsorted section of the array. The naive implementation of such an algorithm is in place.

**Naive Heapsort**. A variant of selection sort is to use a heap-based priority queue to sort the items. To do this, insert all items into a `MaxPQ`

and then remove them one by one. The first such item removed is placed at the end of the array, the next item right before the end, and so forth until that last item deleted is placed in position 0 of the array. Each insertion and deletion takes O(log N) time, and there are N insertions and deletions, resulting in a O(N log N) runtime. With some more work, we can show that heapsort is θ(N log N) in the worst case. This naive version of heapsort takes θ(N) additional space for the array heap representation. It is also possible to use a `MinPQ`

instead.

**In-place Heapsort**. When sorting an array, we can avoid the θ(N) memory cost by treating the array itself as a heap. To do this, we first heapify the array using bottom-up heap construction in O(N log N) time. We then repeatedly delete the max item, swapping it with the last item in the heap. Over time, the heap shrinks from N items to 0 items, and the sorted list grows from 0 items to N items. The resulting version is also θ(N log N) time but does not require creating a separate array heap representation.

**Merge sort**. We can sort by merging, as discussed in an earlier lecture. Mergesort is θ(N log N) and uses θ(N) additional space.

**Inversions**. The number of pairs of elements in a sequence that are out of order. An array with no inversions is ordered. A reverse-sorted array has the maximum number of inversions.

**Insertion sort**. Maintain a sorted subsection at the front of the array. For each item from left to right, repeatedly swap it with its left neighbor until it’s reached its appropriate place in the sorted subsection. The invariant for this type of insertion sort is that every item to the left of position `i`

is in sorted order, and everything to the right has not yet been examined. Every swap fixes exactly one inversion. In the best case, insertion sort takes θ(N) time. In the worst case, θ(N^{2}) time. More generally, runtime is θ(N + K), where K is the number of inversions.

## Recommended Problems

- [Textbook 2.1.6] Which method runs fastest for an array with all keys identical, selection sort or insertion sort?
- [Textbook 2.1.2] What is the maximum number of exchanges involving any particular item during selection sort? What is the average number of exchanges involving an item?
- [Textbook 2.1.8] Suppose that we use insertion sort on a randomly ordered array where items have only one of three key values. Is the running time linear, quadratic, or something in between?
- Mergesort can be optimized when the items in the left subarray are all smaller than the right subarray. Describe an algorithm implementing this optimization and give the runtime of a merge operation for this special case.
- Q3a from CS 61B 15sp Final (Solution)
- Q8a from CS 61B 15sp Final (Solution)
- Q2a, Q2b from CS 61B 17sp Final (Solution)
- Q2a, Q2c, Q2d, Q2e from CS 61B 18sp Final (Solution)