Insertion Sort Algorithm with C, C++, Java, Python Examples

⚡ Smart Summary

Insertion Sort is a comparison-based, in-place sorting method that constructs a sorted list one element at a time. It is stable, adaptive, simple to implement, and well-suited for small or nearly sorted data sets in practice.

  • 📥 Core Idea: Insertion Sort picks each element and shifts it left until it sits in the correct position within the already sorted sublist.
  • 🔁 Insert Operation: Repeated swap-with-left comparisons drive the algorithm, growing the sorted region by one element per outer loop pass.
  • Time Complexity: Best case runs in O(n) for already sorted data, while worst and average cases reach O(n^2) for reversed or jumbled inputs.
  • Properties: The algorithm is online, in-place, stable, and adaptive, which makes it predictable for streaming inserts and partially sorted arrays.
  • 🧪 Code Coverage: Reference implementations are provided in C, C++, and Python so learners can compare loop structures and swap mechanics side by side.
  • 🤖 AI Angle: Modern AI assistants visualize Insertion Sort passes and recommend it when input arrays are short or nearly ordered.

What is Insertion Sort?

Insertion Sort is one of the comparison sort algorithms used to sort elements by iterating on one element at a time and placing the element in its correct position within an already ordered region.

Each element is sequentially inserted into an already sorted list. The size of the already sorted list initially is one. The Insertion Sort algorithm ensures that the first k elements are sorted after the kth iteration of the outer loop.

Because Insertion Sort builds the result incrementally, it is intuitive to teach, easy to debug, and a strong baseline for very small inputs where more complex algorithms would add overhead without measurable gains.

Characteristics of Insertion Sort Algorithm

The algorithm for Insertion Sort has the following important characteristics that explain its behaviour on real workloads:

  • It is a stable sorting technique, so it does not change the relative order of equal elements.
  • It is efficient for smaller data sets but not effective for larger lists where quadratic growth dominates.
  • Insertion Sort is adaptive, which reduces its total number of steps if the input is partially sorted. An Array is provided as input to make it efficient because random access enables constant-time shifts during the inner loop.
  • It is an in-place algorithm, so it does not require auxiliary storage proportional to the input size.

With these traits in mind, the next section explains the core insert operation that powers every pass of the algorithm.

How does Insert Operation work?

In the Insertion Sort algorithm, the insert operation is used to sort unsorted elements. It helps insert a new element into an already sorted list while preserving the existing order of the sorted region.

Pseudocode of the insert operation:

Consider a list A of N elements.

// Insert A[N-1] into sorted sublist A[0..N-2]
for i = N-1 to 1:
    if A[i] < A[i-1], then swap A[i] and A[i-1]
    else stop

Insert Operation work

In the above example, a new element 6 is inserted into an already sorted list. The following steps trace the inner loop as the new element migrates left toward its correct position.

Step 1) Compared with the left adjacent element of A[5], 9 > 6, we swap the position of 9 and 6. Now element 6 is moved to A[4].

Step 2) Now, we compare A[4] and A[3], and we find that A[3] > A[4], so we again swap the position of 6 and 8.

Step 3) Now compare A[3] and A[2]. As A[2] > A[3], we swap the position of 7 and 6.

Step 4) We compare A[1] and A[2]. As A[1] < A[2], the left adjacent element is no longer greater. We conclude that 6 is inserted correctly, and we stop the inner loop here.

How the Insertion Sort Works

The insert operation discussed above is the backbone of Insertion Sort. The insert procedure is executed on every element, and at the end, we get the sorted list as the sorted region grows by one element on every outer pass.

Insertion Sort Works

The figure above demonstrates the working of Insertion Sort in a data structure. Initially, only one element is in the sorted sublist, i.e., 4. After inserting A[1], i.e., 3, the size of the sorted sublist grows to 2, and the algorithm continues this pattern until every element has been placed.

With the conceptual flow in place, the following sections show concrete implementations in C++, C, and Python so you can compare loop structures across languages.

C++ Program for Insertion Sort

The C++ implementation below uses two nested loops: the outer loop selects the next unsorted element, and the inner loop shifts it left until the correct position is found.

#include <iostream>
using namespace std;

int main(){
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};

    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]);

    //printing unsorted list
    cout << "\nUnsorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    }

    int current_element,temp;

    for(int i = 1; i < size_unsorted; i++){
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    cout << "\nSorted: ";
    for(int i = 0 ; i < size_unsorted ; i++){
        cout << unsorted[i] << " ";
    }

    return 0;
}

Output:

Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

C Code for Insertion Sort

The same logic translates directly to C. The standard printf calls replace stream output, but the swap pattern inside the inner loop is identical to the C++ version.

#include <stdio.h>
int main() {
    //unsorted list
    int unsorted[] = {9,8,7,6,5,4,3,3,2,1};

    //size of list
    int size_unsorted = sizeof(unsorted) / sizeof(unsorted[0]);

    //printing unsorted list
    printf("\nUnsorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    int current_element, temp;

    for(int i = 1; i < size_unsorted; i++){
        current_element = unsorted[i];
        for(int j = i-1; j >= 0 && unsorted[j] > current_element; j--){
            //swapping if current element is lesser
            temp = unsorted[j+1];
            unsorted[j+1] = unsorted[j];
            unsorted[j] = temp;
        }
    }

    //printing sorted list
    printf("\nSorted: ");
    for(int i = 0 ; i < size_unsorted ; i++){
        printf("%d ", unsorted[i]);
    }

    return 0;
}

Output:

Output:
Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

Python Program for Insertion Sort

Python supports tuple swapping in a single expression, so the inner loop is more compact than its C and C++ counterparts while preserving the same algorithmic behaviour.

#unsorted list
unsorted = [9,8,7,6,5,4,3,3,2,1]

#size of list
size_unsorted = len(unsorted)

#printing unsorted list
print("\nUnsorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

for i in range(1, size_unsorted):
    current_element = unsorted[i]
    j = i - 1
    while j >= 0 and unsorted[j] > current_element:
        #swapping if current element is lesser
        unsorted[j+1], unsorted[j] = unsorted[j], unsorted[j+1]
        j -= 1

#printing sorted list
print("\nSorted: ", end="")
for i in range(size_unsorted):
    print(unsorted[i], end=" ")

Output:

Unsorted: 9 8 7 6 5 4 3 3 2 1
Sorted: 1 2 3 3 4 5 6 7 8 9

Properties of Insertion Sort

Here are important properties of Insertion Sort that help you decide when it is the right tool:

  • Online: Insertion Sort can sort elements as it receives them. If we have already sorted a list of elements and append more elements to the list, then we do not need to run the entire sorting procedure again. Instead, we only iterate on the newly added elements.
  • In-place: The space complexity of the Insertion Sort algorithm is constant and does not require extra space. This algorithm sorts elements in place.
  • Stable: In Insertion Sort, we do not swap elements if their values are equal. For example, if two elements, x and y, are equal and x appears before y in the unsorted list, then in the sorted list, x will still appear before y. This makes Insertion Sort stable.
  • Adaptive: A sorting algorithm is adaptive if it takes less time when the input elements or a subset of elements are already sorted. As we discussed above, the best running time of Insertion Sort is O(N), and the worst running time is O(N^2). Insertion Sort is one of the adaptive sorting algorithms.

Complexity of Insertion Sort

The complexity discussion below covers both memory usage and run time so you can position Insertion Sort against alternatives such as Bubble Sort and Quick Sort.

Space Complexity

Insertion Sort does not require extra space to sort the elements. The space complexity is constant, i.e., O(1), because only a few temporary variables are used regardless of the input size.

Time Complexity

Because Insertion Sort iterates one element at a time, it requires N-1 passes to sort N elements. For each pass, it may make zero swaps if the elements are already sorted, or it may need many swaps if the elements are arranged in descending order.

  • For pass 1, the minimum swaps required are zero, and the maximum swaps required are 1.
  • For pass 2, the minimum swaps required are zero, and the maximum swaps required are 2.
  • For pass N, the minimum swap required is zero, and the maximum swaps required are N.
  • The minimum swap is zero, so the best time complexity is O(N) for iterating N passes.
  • Total maximum swaps are (1+2+3+4+…+N) i.e., N(N+1)/2, so the worst time complexity is O(N^2).

Here is the important time complexity of Insertion Sort:

  • Worst Case Complexity: O(n^2): Sorting an array in descending order when it is required to be ascending is the worst-case scenario.
  • Best Case Complexity: O(n): The best case occurs when the array is already sorted; the outer loop runs n times, while the inner loop does not run at all. There are only n comparisons, so the complexity is linear.
  • Average Case Complexity: O(n^2): This happens when the elements of the array occur in a jumbled order that is neither ascending nor descending.

FAQs

Choose Insertion Sort for small arrays, nearly sorted data, or streaming inserts where new items arrive after an initial sort. Its low constant overhead and adaptive behaviour often beat more complex algorithms on these workloads.

Yes. Insertion Sort is stable because it never swaps equal values, preserving their original order. It is also in-place because it sorts using only the input array plus a small fixed number of temporary variables, giving O(1) auxiliary space.

The best case is O(n) when the input is already sorted because the inner loop never executes. The worst and average cases are both O(n^2) when the array is reverse sorted or jumbled, due to repeated shifting of elements toward the front of the array.

AI assistants generate step-by-step animations and tables that mark the current element, sorted region, and comparison pointer for each pass. This visualization helps learners trace swaps, spot off-by-one errors, and confirm that the sorted prefix grows by one element on every outer iteration.

Yes. AI-driven selectors inspect array size, distribution, and presortedness, then route small or nearly sorted inputs to Insertion Sort while larger random inputs are routed to Quick Sort or Merge Sort. Hybrid algorithms such as Timsort already apply this idea inside their inner partitions.

Insertion Sort builds the sorted region by inserting each new element into the correct position, while Selection Sort repeatedly finds the minimum of the unsorted region and appends it. Insertion Sort is adaptive and stable; standard Selection Sort is not adaptive and is not naturally stable.

Summarize this post with: