Sorting Algorithms

Often we require data to be ordered according to some criteria but how do we sort the data? This has been an active area of research for decades. Here I compare a few of the more well known algorithms.

Bubble Sort

I think I was in secondary school when I first encountered a sorting algorithm, as part of a computer studies class project we had to implement one.

Bubble sort was the one that was chosen (I can’t remember if it was the teacher or our choice). It’s quite a simple algorithm that “bubbles” up the smallest element of an array towards the top.

Starting at the top of the array compare adjacent elements and swap them if they are in the wrong order (first element is greater than the next one). This process is repeated until all elements are in their correct order.

Here is an implementation in C

void bubble_sort(int *data, int num_items)
{
    int items_swapped;
    
    do
    {
        items_swapped = 0;

        for (int i = 1; i < num_items; i++)
        {
            if (data[i-1] > data[i])
            {
                int temp = data[i-1];
                data[i-1] = data[i];
                data[i] = temp;
                
                items_swapped = 1;
            }            
        }
    } while (items_swapped != 0);
}

Bubble sort is quite naive and performs badly in many cases. A simple inspection of the above function shows that it will execute the outer loop until the inner loop has made no swaps. This means that when the data is completely sorted, one more iteration of the outer loop will be executed.

In the degenerate case when the data to be sorted is in reverse order (i.e. sorted from high to low), it would take \( n \) iterations of the outer loop, for each of these will require n iterations of the inner loop ( \(n \times n \ or \ n^2\) operations).

We say that the performance of the algorithm is \(O(n^2)\).

Big O notation is a way of expressing the relative performance of an algorithm in terms of the number of operations it will take.

We can see how the sort progresses in the average case in the diagram below. Each row is one iteration of the outer loop. The color indicates the value of each element in the array.

Initially the data is randomly arranged but after each iteraton it becomes gradually arranged in similar color order. At the end the color transition between elements is smooth, indicating a smoothed ordered set of data.

                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               

So now that we know the performance of bubble sort can we do any better?

Selection Sort

Selection sort works by finding the smallest element in the array and exchanging it with the first one. This first element is now in it’s correct place and the search resumes for the next smallest element, starting from the next element of the array.

In this way the array is partitioned into two sections. Everything before the current search postion start is sorted and everything else is (potentially) unsorted. The sorted section grows until it covers the whole of the array, the data is then sorted.

Here is an implementation in C

void selection_sort(int *data, int num_items)
{
    for (int i = 0; i < num_items; i++)
    {
        int min = i;
        
        for (int j = i+1; j < num_items; j++)
        {
            if (data[j] < data[min])
            {
                min = j;
            }
        }
        
        int temp = data[min];
        data[min] = data[i];
        data[i] = temp;
    }
}

As the sorted portion of the array grows for each iteration of the outer loop, the search space covered by the inner loop reduces, the perfomance is approximately \(O(n + (n-1) + (n-2) + … + 1)\). Also the inner loop is considerably simpler than bubble sort loop.

                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               

Insertion Sort

Insertion sort is the kind of operation you would carry out when sorting a small set of items by hand for example till receipts into date order. Inspect each item in turn and insert it in to the proper place among those already considered.

In an array this insertion would involve making space for the new item by shuffling down all items after it’s insertion place.

void insertion_sort(int *data, int num_items)
{
    for (int i = 1; i < num_items; i++)
    {
        for (int j = i; j > 0 && (data[j] < data[j-1]); j--)
        {
            int temp = data[j-1];
            data[j-1] = data[j];
            data[j] = temp;
        }
    }
}

Again the performance appears to be \(O(n^2)\) but it does have good performance when the data sets are small and the data is partially sorted. So much so that it is used as a fallback in more complex sorting algorithms for small data sets.

                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               

Merge Sort

Merge sort works by partitioning the data into n sublists of one element each. Pairs of sublists are then merged in sorted order to produce \(n/2\) sublists of each containing two elements. This process repeats until there is only one list remaining containing all the data in sorted order.

Consider the following data to be sorted.

3 2 5 1 6 4 8 7

This would be viewed as 8 single element sublists.

3   2   5   1   6   4   8   7

Pairs of sublists would then be combined in order to create 4 lists of two elements each.

2 3   1 5   4 6   7 8

This would then be repeated to create two sublists of four elements each.

1 2 3 5   4 6 7 8

Finally one more iteration would create the desired sorted data.

1 2 3 4 5 6 7 8
// data[] has the items to sort; work[] is a work array
void merge_sort(int *data, int *work, int n)
{
    // Each 1-element run in data is already "sorted".
    // Make successively longer sorted runs of length 2, 4, 8, 16...
    // until whole array is sorted.
    for (int width = 1; width < n; width = 2 * width)
    {
        // data array  is full of runs of length width.
        for (int i = 0; i < n; i = i + 2 * width)
        {
            // Merge two runs: data[i..i+width-1] and data[i+width..i+2*width-1] to work[]
            // or copy data[i..n-1] to work[] ( if(i+width >= n) )
            merge(data, i, min(i+width, n), min(i+2*width, n), work);
        }

        // Now work array is full of runs of length 2*width.
        // Copy array work to data array for next iteration.
        // A more efficient implementation would swap the roles of data and work.
        copy_array(work, data, n);

        // Now data array is full of runs of length 2*width.
    }
}

// Left run is data[left..right-1].
// Right run is data[right..end-1]
void merge(int *data, int left, int right, int end, int *work)
{
    int i = left;
    int j = right;
    // While there are elements in the left or right runs...
    for (int k = left; k < end; k++) {
        // If left run head exists and is <= existing right run head.
        if (i < right && (j >= end || data[i] <= data[j])) {
            work[k] = data[i];
            i = i + 1;
        } else {
            work[k] = data[j];
            j = j + 1;
        }
    }
}

void copy_array(int *src, int *dest, int n)
{
    for(int i = 0; i < n; i++)
    {
        dest[i] = src[i];
    }
}

int min(int a, int b)
{
    return a < b ? a : b;
}

As can be seen, the implementation for merge sort is much more complicated the the previous algorithms but analysis has shown that it has a performance of \(O(n \space log \space n)\) which is signicantly better than the \(O(n^2)\) performance of the other sort algorithms presented previously.

This increased performance incurs a cost of extra memory. A second array of the same size as the data set. This tradeoff must be taken into account when selecting an sorting algorithm for a particular application.

                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               

Quicksort

I’m not going to cover quicksort in too much detail as this post is already getting a bit long. In a future post I will cover the algorithm in more detail.

Quicksort has similarties to mergesort in that it works by partitioning the data and works in a divide and conquer manner.

The difference is that where mergesort uses an iterative process, quicksort classically uses recursion1 to partition the dataset into repeatedly smaller subsections.

The algorithm selects a pivot element and then and partitions the the other elements into two sub sections one that is less that the pivot element and one that is greater. Recursion is then used to sort the sub sections.

Unlike mergesort a seperate work array is not necessary, the partitioning can be done in place. The crux of the algorithm is selection of the pivot element. There have been many analyses on the choice and how it can affect performance. Some simple choices are :-

Here is an implementation that uses the middle element of the array as the pivot.

void quick_sort(int *data, int num_items)
{
    if (num_items < 2)
    {
        return;
    }
 
    // Choose the middle element as the pivot
    int pivot = data[num_items / 2];
 
    int i;
    int j;
    
    for (i = 0, j = num_items - 1; ; i++, j--)
    {
        // Find the first element that is less than the pivot
        while (data[i] < pivot)
        {
            i++;
        }
  
        // Find the last element that is greater than the pivot
        while (data[j] > pivot)
        {
            j--;
        }
      
        // If the two indices have crossed then terminate the loop
        if (i >= j)
        {
            break;
        }
 
        // Swap the elements at [i] and [j]
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
 
    // Thw element at [i] is in the correct position
    // Now recurse to sort the two partiions either side of it.
    quick_sort(data, i);
    quick_sort(data + i, num_items - i);
}
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               
                                                                                                                               

Comparison

So on the face of it it would seem that bubble sort, selection sort and quick sort would take about the same time as they all have around the same number of iterations of the main loop, conversely merge sort should be quicker than all of them because it has significantly less iterations.

Time to sort a 64 element array (us)
Bubble Sort 11.8
Selecton Sort 5.9
Insertion Sort 4.9
Merge Sort 3.6
Quick Sort 1.8

Understandably bubble sort is the worst, selection and insertion sort have similar performance. Mergesort is the best of the none recursive algorithms and this could be improved by swapping the data and work array pointers after each iteration instead of copying the work array back to the data array.

Quicksort is twice as fast as mergesort but has an recursive implementation. For desktop environments this should not pose a problem, however in embedded applications where processors have much smaller memories this could cause the problem of blowing the stack in a degenerate case.

It is quite often the case that in embedded systems (safety critical applications in particular), local coding rules forbid the use of recursion.

In this case my personal choice would be merge sort if enough memory could be spared for the work array. Failing that I would choose insertion sort.

There is now a gitbug repository of the code in this article at https://github.com/Systemrate/sort_test.git


  1. Iterative implementations are possible but they are more complex and more fragile in the face of implementation tuning. ↩︎