Sort an almost ordered sequence efficiently by using insertion sort, whose running time improves when few elements are far from their final positions.
Nearly sorted insertion sort is ordinary insertion sort applied to input that is already close to sorted order. Insertion sort adapts well to this case because each element moves only a short distance.
You use it when the input has small disorder, such as data produced by appending a few new records, merging mostly ordered logs, or correcting a sequence after minor edits.
Problem
Given an array ( A ) of length ( n ), sort it under the assumption that most elements are already near their final sorted positions.
A useful measure is the number of inversions. An inversion is a pair ( (i, j) ) such that:
[ i < j \quad \text{and} \quad A[i] > A[j] ]
Insertion sort runs quickly when the number of inversions is small.
Algorithm
Scan from left to right. At each index, insert the current value into the already sorted prefix.
nearly_sorted_insertion_sort(A):
for i in 1..length(A)-1:
x = A[i]
j = i - 1
while j >= 0 and A[j] > x:
A[j + 1] = A[j]
j = j - 1
A[j + 1] = x
return AExample
Input:
[ A = [1, 2, 4, 3, 5, 7, 6, 8] ]
Only a few adjacent pairs are out of order. Insertion sort performs a small number of shifts:
| step | inserted | result |
|---|---|---|
| 1 | 2 | [1, 2, 4, 3, 5, 7, 6, 8] |
| 2 | 4 | [1, 2, 4, 3, 5, 7, 6, 8] |
| 3 | 3 | [1, 2, 3, 4, 5, 7, 6, 8] |
| 4 | 5 | [1, 2, 3, 4, 5, 7, 6, 8] |
| 5 | 7 | [1, 2, 3, 4, 5, 7, 6, 8] |
| 6 | 6 | [1, 2, 3, 4, 5, 6, 7, 8] |
Correctness
Before processing index ( i ), the prefix ( A[0..i-1] ) is sorted. The algorithm shifts all elements greater than ( A[i] ) one position to the right and places ( A[i] ) into the unique position that preserves sorted order.
By induction, the prefix remains sorted after every iteration. After the final iteration, the whole array is sorted.
Complexity
Let ( I ) be the number of inversions in the input.
| input | time |
|---|---|
| already sorted | ( O(n) ) |
| nearly sorted | ( O(n + I) ) |
| reverse sorted | ( O(n^2) ) |
Space:
[ O(1) ]
Stability
The algorithm is stable when it shifts only elements strictly greater than the inserted value.
while j >= 0 and A[j] > x:Equal elements keep their original relative order.
When to Use
Use nearly sorted insertion sort when:
- input is almost sorted
- changes since the last sorted state are small
- the array is small
- stable in-place sorting is useful
It is often used inside hybrid sorting algorithms for small runs or nearly ordered regions.