Insertion sort vs. selection sort (time complexity and performance)
yourbasic.org
Insertion sort
Insertion sort is a simple sorting algorithm with quadratic worst-case time complexity, but in some cases it’s still the algorithm of choice.
- It’s efficient for small data sets. It typically outperforms other simple quadratic algorithms, such as selection sort or bubble sort.
- It’s adaptive: it sorts data sets that are already substantially sorted efficiently. The time complexity is O(nk) when each element is at most k places away from its sorted position.
- It’s stable: it doesn’t change the order of elements with equal keys.
- It’s in-place: it only requires a constant amount of additional memory.
- It has good branch prediction characteristics, typically limited to a single misprediction per key.
// InsertionSort sorts the elements of a in ascending order.
func InsertionSort(a []int) {
for j := 1; j < len(a); j++ {
// Invariant: a[:j] contains the same elements as
// the original slice a[:j], but in sorted order.
key := a[j]
i := j - 1
for i >= 0 && a[i] > key {
a[i+1] = a[i]
i--
}
a[i+1] = key
}
}
Selection sort
In practice, selection sort generally performs worse than insertion sort.
- It doesn’t adapt to data and always performs a quadratic number of comparisons.
- However, it moves each element at most once.
// SelectionSort sorts the elements of a in ascending order.
func SelectionSort(a []int) {
for j := 0; j < len(a)-1; j++ {
// Invariant: a[:j] contains the first j elements
// of the final sorted slice.
minPos := j
for i := j + 1; i < len(a); i++ {
if a[i] < a[minPos] {
minPos = i
}
}
a[j], a[minPos] = a[minPos], a[j]
}
}
Further reading
See Optimized quicksort algorithm explained for a fast Quicksort implementation that uses Insertion sort to improve performance.