Insertion sort that uses binary search to find the insertion position, reducing comparisons.
Binary insertion sort improves insertion sort by using binary search to locate the correct insertion position in the sorted prefix. This reduces the number of comparisons, though element shifting still dominates the runtime.
The algorithm keeps the same structure as insertion sort but replaces the linear scan with a logarithmic search.
Problem
Given a sequence of length , reorder it such that
Algorithm
For each element , use binary search on the sorted prefix to find its correct position, then shift elements to insert it.
binary_insertion_sort(A):
n = length(A)
for i from 1 to n - 1:
key = A[i]
left = 0
right = i
while left < right:
mid = (left + right) // 2
if A[mid] <= key:
left = mid + 1
else:
right = mid
for j from i downto left + 1:
A[j] = A[j - 1]
A[left] = keyExample
Let
Step 1:
Insert 2 into [5]
→ [2,5,4,6,1]
Step 2:
Insert 4 into [2,5] using binary search
→ [2,4,5,6,1]
Step 3:
Insert 6 into [2,4,5]
→ [2,4,5,6,1]
Step 4:
Insert 1 into [2,4,5,6]
→ [1,2,4,5,6]
Correctness
At each iteration, binary search identifies the correct insertion position within the sorted prefix. Shifting elements preserves order, and inserting the key maintains sorted structure. The invariant that the prefix is sorted holds for all iterations.
Complexity
| case | comparisons | time |
|---|---|---|
| best | comparisons | |
| worst | comparisons | |
| average | comparisons |
Shifting dominates cost:
Space complexity:
Properties
- stable
- in-place
- fewer comparisons than insertion sort
- same asymptotic time due to shifts
When to Use
Binary insertion sort is useful when comparisons are expensive but memory moves are relatively cheap. It also appears in hybrid sorting algorithms where reducing comparison count matters.
Implementation
def binary_insertion_sort(a):
for i in range(1, len(a)):
key = a[i]
left, right = 0, i
while left < right:
mid = (left + right) // 2
if a[mid] <= key:
left = mid + 1
else:
right = mid
for j in range(i, left, -1):
a[j] = a[j - 1]
a[left] = key
return afunc BinaryInsertionSort[T constraints.Ordered](a []T) {
for i := 1; i < len(a); i++ {
key := a[i]
left, right := 0, i
for left < right {
mid := (left + right) / 2
if a[mid] <= key {
left = mid + 1
} else {
right = mid
}
}
for j := i; j > left; j-- {
a[j] = a[j-1]
}
a[left] = key
}
}