Insertion Sort
What is Insertion Sort?
Insertion sort builds the sorted array one element at a time. It picks each element and inserts it into its correct position in the already-sorted portion, shifting larger elements right to make room. Think of how you sort playing cards in your hand.
| Case | Time | Space | Stable? |
|---|---|---|---|
| Best | O(n) — already sorted | O(1) | Yes |
| Average | O(n²) | O(1) | Yes |
| Worst | O(n²) — reverse sorted | O(1) | Yes |
How it Works
For array [12, 11, 13, 5, 6]:
- i=1: key=11. 12 > 11 → shift 12 right → insert 11 →
[11, 12, 13, 5, 6] - i=2: key=13. 12 < 13 → no shift →
[11, 12, 13, 5, 6] - i=3: key=5. 13,12,11 > 5 → shift all → insert 5 →
[5, 11, 12, 13, 6] - i=4: key=6. 13,12,11 > 6 → shift → insert 6 →
[5, 6, 11, 12, 13]✓
import java.util.Arrays;
public class InsertionSort {
static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i]; // element to be inserted
int j = i - 1;
// Shift elements greater than key one position right
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key; // insert key at correct position
}
}
// Recursive insertion sort
static void insertionSortRec(int[] arr, int n) {
if (n <= 1) return;
insertionSortRec(arr, n - 1); // sort first n-1 elements
int key = arr[n - 1];
int j = n - 2;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6};
System.out.println("Before: " + Arrays.toString(arr));
insertionSort(arr);
System.out.println("After: " + Arrays.toString(arr));
// After: [5, 6, 11, 12, 13]
// Best case: already sorted — O(n)
int[] sorted = {1, 2, 3, 4, 5};
insertionSort(sorted);
System.out.println("Sorted: " + Arrays.toString(sorted));
}
}
/*
* Insertion sort is excellent for:
* - Small arrays (n < 20) — low overhead
* - Nearly sorted data — O(n) in best case
* - Online sorting — can sort as data arrives
* - Used as a subroutine in Timsort (Python/Java's built-in sort)
*/
Step-by-Step Trace
For array [12, 11, 13, 5, 6]:
| i | key | Sorted Portion | Array After Insert |
|---|---|---|---|
| 1 | 11 | [12] | [11, 12, 13, 5, 6] — 11 inserted before 12 |
| 2 | 13 | [11, 12] | [11, 12, 13, 5, 6] — 13 stays in place |
| 3 | 5 | [11, 12, 13] | [5, 11, 12, 13, 6] — 5 inserted at front |
| 4 | 6 | [5, 11, 12, 13] | [5, 6, 11, 12, 13] — 6 inserted after 5 |
When to Use Insertion Sort
- Small arrays (n < 20) — very low overhead, often faster than O(n log n) sorts
- Nearly sorted data — O(n) in best case, only a few shifts needed
- Online sorting — can sort data as it arrives, one element at a time
- Used as a subroutine in Timsort (Python's and Java's built-in sort for small runs)
- Avoid for large random datasets — O(n²) average case