Skip to main content

Command Palette

Search for a command to run...

Insertion Sort

Updated
6 min read
J

I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class.

At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out.

In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.

Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. However, it has the advantage of being simple to understand and implement.

Here's a step-by-step explanation of how insertion sort works, using a small array of 5 elements as an example:

Let's assume our array is: [5, 3, 4, 1, 2]

Initial State:

5 3 4 1 2
↑

(The arrow points to the current element being sorted)

Iteration 1:

  • No action is needed on the first element (5), as it is the only element in the sorted section.

Iteration 2 (Sorting 3):

5 3 4 1 2
  ↑
  • Compare 3 with 5. Since 3 is smaller, swap them.

After Iteration 2:

3 5 4 1 2
  ↑

Iteration 3 (Sorting 4):

3 5 4 1 2
    ↑
  • Compare 4 with 5, since 4 is smaller, swap them.

  • Then compare 4 with 3, no swap needed as 3 is smaller.

After Iteration 3:

3 4 5 1 2
    ↑

Iteration 4 (Sorting 1):

3 4 5 1 2
      ↑
  • Compare 1 with 5, 1 is smaller, swap them.

  • Compare 1 with 4, 1 is smaller, swap them.

  • Compare 1 with 3, 1 is smaller, swap them.

After Iteration 4:

1 3 4 5 2
      ↑

Iteration 5 (Sorting 2):

1 3 4 5 2
        ↑
  • Compare 2 with 5, 2 is smaller, swap them.

  • Compare 2 with 4, 2 is smaller, swap them.

  • Compare 2 with 3, 2 is smaller, swap them.

After Iteration 5:

1 2 3 4 5
        ↑

Final Sorted Array:

1 2 3 4 5

The array is now sorted.

Here's the pseudocode for the insertion sort algorithm:

function insertionSort(array)
    for i from 1 to length(array)
        // The current element to be sorted
        key = array[i]

        // Initialize j to the position before the current element
        j = i - 1

        // Move elements of array[0..i-1], that are greater than key,
        // to one position ahead of their current position
        while j >= 0 and array[j] > key
            array[j + 1] = array[j]
            j = j - 1

        // Place the key at its correct position
        array[j + 1] = key

    return array

Here's a brief explanation of each step:

  1. Start with the second element: The algorithm starts iterating from the second element of the array, as the first element is considered sorted by itself.

  2. Key Element: This is the element which is currently being sorted. In each iteration, the algorithm tries to insert the key element into its correct position in the sorted part of the array.

  3. Shifting Elements: If the key element is smaller than the elements in the sorted part of the array, those elements are shifted one position to the right to make space for the key element.

  4. Insert the Key: Once the correct position is found (where all elements to the left are smaller), the key is placed in its rightful position.

  5. Repeat Until Sorted: This process is repeated for each element until the entire array is sorted.

Here's the C code for the insertion sort algorithm, followed by a detailed explanation:

#include <stdio.h>

void insertionSort(int arr[], int n) {
    int i, key, j;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;

        // Move elements of arr[0..i-1] that are greater than key,
        // to one position ahead of their current position
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

void printArray(int arr[], int n) {
    int i;
    for (i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");
}

int main() {
    int arr[] = {12, 11, 13, 5, 6};
    int n = sizeof(arr) / sizeof(arr[0]);

    insertionSort(arr, n);
    printArray(arr, n);

    return 0;
}

Explanation of the Code:

  1. Header File Inclusion:

     #include <stdio.h>
    

    This includes the Standard Input Output library for using the printf function.

  2. Insertion Sort Function:

     void insertionSort(int arr[], int n) {
         ...
     }
    

    This function takes an array arr[] and its size n as arguments.

  3. Looping Through the Array:

     for (i = 1; i < n; i++) {
         ...
     }
    

    The loop starts from the second element (index 1) since the first element is considered sorted by default.

  4. Key Element:

     key = arr[i];
    

    The key variable holds the value of the current element being sorted.

  5. Finding the Correct Position for Key:

     while (j >= 0 && arr[j] > key) {
         arr[j + 1] = arr[j];
         j = j - 1;
     }
    

    This while loop moves each element that is greater than key one position to the right to make space for inserting the key.

  6. Inserting the Key:

     arr[j + 1] = key;
    

    Once the correct position is found, the key is placed in its rightful position.

  7. Print Function:

     void printArray(int arr[], int n) {
         ...
     }
    

    This function prints the elements of the array. It's used to display the array before and after sorting.

  8. Main Function: The main function demonstrates the usage of insertionSort. It defines an array, calls insertionSort on it, and then prints the sorted array.

This C program efficiently implements the insertion sort algorithm, showcasing its utility in sorting small arrays. The key concept is the repositioning of elements to insert each element into its correct position, making the left part of the array sorted at each step.

Complexity analysis of the insertion sort algorithm involves evaluating its time complexity and space complexity. Let's break down both of these aspects:

Time Complexity

  1. Best Case (Array is already sorted):

    • O(n)

    • In the best-case scenario, where the array is already sorted, the inner loop (the while loop) does not perform any swaps. The algorithm only needs to iterate through the array once, making the time complexity linear.

  2. Average Case and Worst Case (Array is partially sorted or not sorted):

    • O(n^2)

    • In the average and worst cases, the inner loop can perform a significant amount of comparisons and swaps. In the worst case, where the array is sorted in reverse order, the inner loop does the maximum amount of work. For each element, it may need to compare and shift almost every other element, leading to a quadratic time complexity.

Space Complexity

  • O(1)

  • Insertion sort is an in-place sorting algorithm. It doesn't require any additional space that grows with the input size. The space used by the variables i, j, and key is constant, regardless of the size of the input array.

Important to note

  • Best Case Time Complexity: O(n)

  • Average Case Time Complexity: O(n^2)

  • Worst Case Time Complexity: O(n^2)

  • Space Complexity: O(1)

Insertion sort is efficient for small datasets or nearly sorted datasets because its overhead is low. However, its efficiency decreases significantly for large, unsorted datasets due to its quadratic time complexity.

More from this blog

Jyotiprakash's Blog

251 posts

I'm Jyotiprakash, a software dev and professor at KIIT, with expertise in system programming.