Select Sorts
Select Sorts
A select sort operates by repeatedly selecting the smallest data element of an unsorted portion of the array and moving it to the end of a sorted portion. Thus, at each step, the data items will be arranged into two parts:
- A sorted part; and
- An unsorted part in which each element is at least as large as all elements in the sorted part.
The following figure illustrates this arrangement.
Initially, the sorted part will be empty. At each step, the unsorted
part is rearranged so that its smallest element comes first. As a
result, the sorted part can now contain one more element, and the
unsorted part one fewer element. After
The approach outlined above can be implemented in various ways. The main difference in these implementations is in how we rearrange the unsorted part to bring its smallest element to the beginning of that part. The most straightforward way to do this is to find the smallest element in this part, then swap it with the first element in this part. The resulting algorithm is called selection sort. It requires nested loops. The outer loop index keeps track of how many elements are in the sorted part. The unsorted part then begins at this index. The inner loop is responsible for finding the smallest element in the unsorted part. Once the inner loop has finished, the smallest element is swapped with the first element in the unsorted part.
Note that the inner loop in selection sort iterates once for every
element in the unsorted part. On the first iteration of the outer loop,
the unsorted part contains all
As we will see in what follows,
Performance issues aside, however, there is one positive aspect to selection sort. This aspect has to do with sorting by keys. Consider, for example, the rows of a spreadsheet. We often want to sort these rows by the values in a specific column. These values are the sort keys of the elements. In such a scenario, it is possible that two data elements are different, but their sort keys are the same. A sorting algorithm might reverse the order of these elements, or it might leave their order the unchanged. In some cases, it is advantageous for a sorting algorithm to leave the order of these elements unchanged. For example, if we sort first by a secondary key, then by a primary key, we would like for elements whose primary keys are equal to remain sorted by their secondary key. Therefore, a sorting algorithm that always maintains the original order of equal keys is said to be stable. If we are careful how we implement the inner loop of selection sort so that we always select the first instance of the smallest key, then this algorithm is stable.
Another implementation of a select sort
is bubble sort. It rearranges the unsorted part by swapping adjacent
elements that are out of order. It starts with the last two elements
(i.e., the elements at locations
Like selection sort, bubble sort is stable. In the worst case, however,
the performance of bubble sort is even worse than that of selection
sort. It is still in
A select sort that significantly outperforms selection sort is known as heap sort. This algorithm is based on the idea that a priority queue can be used to sort data — we first place all items in a priority queue, using the values themselves as priorities (if we are sorting by keys, then we use the keys as priorities). We then repeatedly remove the element with largest priority, filling the array from back to front with these elements.
We can optimize the above algorithm by using a priority queue
implementation called a binary heap, whose implementation details we
will only sketch. The basic idea is that we can form a binary tree from
the elements of an array by using their locations in the array. The
first element is the root, its children are the next two elements, their
children are the next four elements, etc. Given an array location, we
can then compute the locations of its parent and both of its children.
The priorities are arranged so that the root of each subtree contains
the maximum priority in that subtree. It is possible to arrange the
elements of an array into a binary heap in
Heap sort then works by pre-processing the array to arrange it into a binary heap. The binary heap then forms the unsorted part, and it is followed by the sorted part, whose elements are all no smaller than any element in the unsorted part. While this arrangement is slightly different from the arrangement for the first two select sorts, the idea is the same. To rearrange the unsorted part, it:
- Copies the first (i.e., highest-priority) element to a temporary variable.
- Removes the element with maximum priority (i.e., the first element).
- Places the copy of the first element into the space vacated by its removal at the beginning of the sorted part.
Heap sort runs in
On the other hand, we will also see that heap sort is an important component of an efficient hybrid algorithm. This algorithm is one of the best general-purpose sorting algorithms; in fact, it is used by .NET’s Array.Sort method. We will examine this approach in “Hybrid Sorts”.