Insertion sort is one of the most popular sorting algorithms. Its popularity is not because of its performance but for its simplicity. Its performance is not as good as quicksort or shellsort for large number of inputs but it is very simple like bubble sort. It is often used for less number of elements especially when the input list or array is substantially sorted. Here we’ll see how to implement insertion sort in C programming language. We’ll also see its performance in various input conditions.

### Insertion Sort Algorithm

In insertion sort, at any point of time, there will be two sub-arrays, one is sorted and other is not. One item (element) is taken from the unsorted sub-array and inserted in the sorted sub-array such that the sorted sub-array remains sorted. This process continues until the while array becomes sorted. At every stage the task is to take an element and insert that to an appropriate place, that’s why the name is insertion sort.

Insertion sort is often compared the way we sort cards in our hand in the game of cards. We keep our cards sorted in our hand in time of dealing. When we get a new card from the dealer, our job is to insert the card at right place such the cards in our hand remain sorted. To do that we compare the new card with the right most card in our hand. If the new card is greater than the right most card, then we place the card next to right most card, otherwise, we compare the card with the second right most card. If the new card is greater than the second right most card then place it next to the second right most card, otherwise, continue the process until the new card gets a right place. If the new card is smaller than any card in hand then it will get the left most position. Same thing we do with our array in case of insertion sort.

### Graphical Illustration of Insertion Sort

The diagram shows how insertion sort works. At step 1, the array is sub-divided into two parts. First element is one part and rest of the elements come in the second part. First sub-array will be always sorted. At step 1, as there is only one element in the left sub-array, it is sorted by default. Then take the first element of the right sub-array and find a right place in the left sub-array to insert the element such that the left sub-array remains sorted. In this case 4 will come before 6. Similar process continues until all elements from right sub-array come to the left sorted sub-array.

### Implementation of Insertion Sort in C

Here is the implementation of insertion sort in C programming.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <stdio.h> void insertion_sort(int *arr, int n) { int i = 0, j = 0, tmp = 0; for (i = 1; i < n; i++) { tmp = arr[i]; j = i - 1; while(j >= 0 && tmp < arr[j]) { arr[j+1] = arr[j]; j--; } arr[j+1] = tmp; } } void main() { int arr[] = {54, 66, 31, 10, 4, 77, 32, 1, 56}; int i = 0; printf("Array before sorting: "); for (i = 0; i < (sizeof(arr)/sizeof(int)); i++) printf(" %d", arr[i]); printf("\n"); insertion_sort(arr, sizeof(arr)/sizeof(int)); printf("Array after sorting: "); for (i = 0; i < (sizeof(arr)/sizeof(int)); i++) printf(" %d", arr[i]); printf("\n"); } |

The *insertion_sorted()* function takes an array as input and applies insertion sort algorithm to sort that array. The outer loop iterates *n-1* times where *n* is the number of elements in the array. The inner loop finds the appropriate position for *i-th* element in first *i* elements in the array which are already sorted. As soon as it find the right place *(j+1)* it terminates. The *i-th* element is place in the right place (*j+1 th* position) outside the inner loop.

Output of the program:

1 2 |
Array before sorting: 54 66 31 10 4 77 32 1 56 Array after sorting: 1 4 10 31 32 54 56 66 77 |

### Performance of Insertion Sort

**Worst case:** Worst case running time of insertion sort in *Big-O* notation is O(N_{2}). Worst case scenario occurs when the array is in reverse order we are sorting for. For example, if we want to sort an array in ascending order and the array is in the descending order to begin with. In this case we’ll have maximum number of comparisons.

The above diagram shows how insertion sort performs in worst case condition. It shows how number of comparisons increases with the number of input elements. In this case running time is directly proportional to number of comparisons. If you look into the graph or table carefully, you’ll notice that if the number of input elements doubles the number of comparisons is increased by four times. If the number of input elements increases by four times, then number of comparisons is increased by sixteen times. That’s why the running time is O(N_{2}).

**Average case:** Average case running time of insertion sort in *Big-O* notation is O(n_{2}). Average case occurs for an array where the elements are in random order at the beginning.

The above diagram shows the performance of insertion sort in average case. Here the actual number of comparisons is less compare than that of the worst case. But the growth rate is same as the worst case. Here also If the number of input elements are doubled, the number of comparisons will be increased by four times. Similarly if the number of elements increases by four times, the number of comparisons increases sixteen times.

**Best case:** Best case running time of insertion sort in *Big-O* notation is O(N). Best case scenario occurs if the array is already sorted. In that case the inner loop will terminate immediately after first comparison.

In best case the number of comparison required is linear with respect to the number of inputs. That means if we double the number of inputs, the number of comparisons required will also be double.

The diagram below compares three conditions (worst, average and best cases)

Running time in best case is negligible compare to worst or best cases for large number of input elements. The time requirement for average case is always less than worst case but their growth rate is same.