Insertion sort is a sorting algorithm that while quite inefficient, is really simple to implement. In principle, it involves looping over the array, checking if the current value is greater than the previous value, and if it isn’t we insert it into the ‘correct’ spot of the previously sorted values.

Invariant

The invariant of an insertion sort is that at the start of the loop all elements to the left of the current iteration (), are already sorted.

Implementation

#include <iostream>  
  
int array[] = {1, 4, 2, 9, 3, 0};  
int n = sizeof(array) / sizeof(array[0]);  
  
int main() {  
    int i = 1; // i starts at the second element  
    for(i; i < n; i++) { //for each element in the array  
        int key = array[i]; //we assign the element to be swapped at i  
        int j = i - 1; // we assign the previous index j, the start of the array to be checked against  
        while(j >= 0 && key < array[j]) { //we then perform an insert on the already sorted array  
            array[j + 1] = array[j]; // we shift elements to the right. This overwrites the value to be shifted, so that's why we need to keep it in the key local.  
            j--; //decrement, we're going backwards into the already sorted array  
        }  
  
        array[j + 1] = key; // we reinsert it when the loop is done, i.e j represents the value of the value where key < j is no longer true  
    }  
    
    for(int i = 0; i < n; i ++) {  
        std::cout << "Array is: " << array[i] << std::endl;  
    }  
  
}

Complexity

The time complexity of insertion sort is amongst the worst possible complexities for common sorting algorithms, with a worst case of:

Conceptually, this is due to the algorithm having to iterate twice over the length of the data. It iterates once per element, and for each element it will iterate over the entirety of the left already sorted side of the list.

This is why for the most part, aside from educational purposes insertion sort is rarely used in practice.