Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Insertion Sort: Time Complexity Analysis

Welcome back! In our last lesson, you successfully implemented the Insertion Sort algorithm in C and saw how it works by building a sorted subarray one element at a time. You even modified it to sort in descending order, showing you have a solid grasp of its core comparison logic.

Today, we will shift our focus from implementation to analysis. Our goal is to analyze the time complexity of Insertion Sort, specifically identifying its best-case and worst-case scenarios. You'll discover that, unlike Bubble Sort and Selection Sort, Insertion Sort's performance is highly sensitive to the initial order of the data, which gives it a unique advantage in certain situations.

1. Analyzing Performance: Best vs. Worst Case

As a quick refresher from our module on algorithm analysis, when we measure time complexity, we count the fundamental operations (like comparisons and assignments/shifts) an algorithm performs relative to the input size, n.

For many algorithms, the number of operations depends not just on n, but also on the specific arrangement of the input data. This leads us to consider different scenarios:

  • Best Case: The input arrangement that requires the fewest operations.
  • Worst Case: The input arrangement that requires the most operations.
  • Average Case: The expected performance for a random input.

Today, we'll dissect the best and worst cases for Insertion Sort.

2. Worst-Case Scenario:

Let's start by thinking about what kind of input would make Insertion Sort work the hardest. The algorithm's inner while loop is responsible for shifting elements. This loop runs as long as the key is smaller than the elements in the sorted portion of the array.

The maximum number of shifts and comparisons will occur if every new element (key) is the smallest one seen so far, forcing it to be compared against and shifted past all the elements already in the sorted portion. This happens when the array is sorted in descending (reverse) order.

Let's watch a detailed breakdown of this scenario.

L-3.7: Insertion Sort | Time Complexity Analysis | Stable Sort | Inplace Sorting

The video "Insertion Sort | Time Complexity Analysis" from the Gate Smashers channel provides an excellent step-by-step count of the operations for the worst-case scenario.

Watch the section that analyzes the worst case. The presenter demonstrates that for a reverse-sorted array, inserting each new element requires comparing it with all previously sorted elements. Pay close attention to how they derive the sum 1 + 2 + 3 + ... + (n-1).

As the video explains, for an array of size n sorted in reverse order:

  • To insert the 2nd element, you need 1 comparison and 1 shift.
  • To insert the 3rd element, you need 2 comparisons and 2 shifts.
  • ...
  • To insert the n-th element, you need n-1 comparisons and n-1 shifts.

The total number of operations is proportional to the sum . This is an arithmetic series that sums to , which simplifies to . In Big-O notation, we drop the lower-order terms and constants, leaving us with a worst-case time complexity of .

3. Best-Case Scenario:

Now, let's consider the opposite scenario: what input requires the least amount of work?

This occurs when the while loop's condition, array[j] > key, is false on the very first check. This means the key is already in its correct position relative to the sorted subarray. This ideal situation happens when the array is already sorted in ascending order.

Let's return to the same video to see this analysis.

L-3.7: Insertion Sort | Time Complexity Analysis | Stable Sort | Inplace Sorting

We'll continue with the Gate Smashers video to analyze the best-case scenario.

Now, watch the section covering the best case. Notice that for each element in the outer loop, only one comparison is made, and the inner while loop's body never executes.

In the best-case scenario:

  • The outer for loop still runs n-1 times (from the second element to the last).
  • For each of these n-1 iterations, the inner while loop performs only one comparison and its condition is immediately false. No shifting occurs.

Therefore, the total number of comparisons is simply n-1. This gives Insertion Sort a remarkable best-case time complexity of . This linear performance makes it one of the fastest sorting algorithms for data that is already (or is very nearly) sorted.

4. Reading and Visualizing the Complexities

To solidify these concepts, let's look at them in a textual format and then visualize what this performance difference actually looks like.

Insertion Sort Algorithm

The GeeksforGeeks article on Insertion Sort provides a concise summary of its complexity.

Please read the section titled "Complexity Analysis of Insertion Sort". This will reinforce the O(n) best-case and O(n^2) worst-case complexities we just discussed. Also, read the small Q&A section below it titled "What are the Boundary Cases of the Insertion Sort algorithm?" which summarizes the key point.

The difference between linear growth and quadratic growth is dramatic. The following graph illustrates the runtime of Insertion Sort for its best, average, and worst cases as the number of elements increases.

This graph shows the runtime of Insertion Sort for different scenarios. The best case (yellow line, O(n)) grows linearly and very slowly. The worst and average cases (red and blue lines, O(n²)) curve upwards sharply, showing much faster growth in runtime as the input size 'n' increases.

As you can see, the curve quickly becomes very steep, meaning the algorithm slows down significantly for large, unsorted lists. In contrast, the line remains nearly flat, showing how efficient it is on sorted data. The average case, for randomly ordered data, also trends towards .

Conclusion

In this lesson, we dissected the performance of Insertion Sort and uncovered its most important characteristic: its adaptability to the input data.

Key Takeaways:

  • Worst-Case Complexity is : This occurs when the input array is sorted in reverse order, forcing a maximum number of comparisons and shifts for each element.
  • Best-Case Complexity is : This occurs when the input array is already sorted. The algorithm only needs to make a single comparison for each element to confirm its position.
  • Average-Case Complexity is : For a typical, randomly ordered array, the performance is quadratic.
  • Practical Use: Due to its best-case complexity, Insertion Sort is an excellent choice for sorting lists that are small or nearly sorted.

Preview of the Next Lesson:
We've now covered three sorting algorithms—Bubble, Selection, and Insertion—that all share a worst-case complexity of . Is it possible to sort more efficiently? The answer is yes. In the next module, we will explore Merge Sort, our first algorithm based on the powerful "divide and conquer" strategy. This will introduce you to the highly efficient complexity class, which is a game-changer for sorting large datasets.

Can't find a good explanation? Sign up and we'll make it for you

Sign up