I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

1. Overview

In this tutorial, we’re going to discuss the Insertion Sort algorithm and have a look at its Java implementation.

Insertion Sort is an efficient algorithm for ordering a small number of items. This method is based on the way card players sort a hand of playing cards.

We start with an empty left hand and the cards laid down on the table. We then remove one card at a time from the table and insert it into the correct position in the left hand. To find the correct position for a new card, we compare it with the already sorted set of cards in the hand, from right to left.

Let’s start by understanding the algorithm steps in pseudocode form.

2. Pseudocode

We’re going to present our pseudocode for insertion sort as a procedure called INSERTION-SORT, taking as parameter an array A[1 .. n] of n items to be sorted. The algorithm sorts the input array in-place (by rearranging the items within the array A).

After the procedure has finished, the input array A contains a permutation of the input sequence but in sorted order:

The index i indicates the position of the current item in the array to process.

We begin from the second item as by definition an array with one item is considered to be sorted. The item at index i is called a key. Once having the key, the second part of the algorithm deals with finding its correct index. If the key is smaller than the value of the item at index j, then the key moves one position to the left. The process continues until the case when we reach an element being smaller than the key.

It’s important to note that before starting the iteration for finding the correct position of the key at index i, the array A[1 .. j – 1] is already sorted.

3. Imperative Implementation

For the imperative case, we’re going to write a function called insertionSortImperative, taking as a parameter an array of integers. The function starts iterating over the array from the second item.

At any given time during the iteration, we could think of this array as being logically divided into two portions; the left side being the sorted one and right side containing the items not yet sorted.

An important note here is that after finding the correct position at which we’ll insert the new item, we shift (and not swap) the items to the right to free a space for it.

And this is what the call stack looks like for an input array of 6 items:

insertionSortRecursive(input, 6)
insertionSortRecursive(input, 5) and insert the 6th item into the sorted array
insertionSortRecursive(input, 4) and insert the 5th item into the sorted array
insertionSortRecursive(input, 3) and insert the 4th item into the sorted array
insertionSortRecursive(input, 2) and insert the 3rd item into the sorted array
insertionSortRecursive(input, 1) and insert the 2nd item into the sorted array

5. Time and Space Complexity

The time taken by the INSERTION-SORT procedure to run is O(n^2). For each new item, we iterate from right to left over the already sorted portion of the array to find its correct position. Then we insert it by shifting the items one position to the right.

The algorithm sorts in place so its space complexity is O(1) for the imperative implementation and O(n) for the recursive implementation.

6. Conclusion

In this tutorial, we saw how to implement insertion sort.

This algorithm is useful for sorting a small number of items. It becomes inefficient when sorting input sequences having more than 100 items.

Keep in mind that despite its quadratic complexity it sorts in place without the need of auxiliary space as is the case for merge sort.