Shell sort
Insertion sort on items gap positions apart, with gaps shrinking down to 1; far-away items get near their place early.
Insertion sort is very fast on a nearly sorted array, but an item far from its place has to walk there one position
at a time. Shell sort fixes this with a gap: first it insertion-sorts the items that are gap positions apart, so
items reach their rough place in long jumps. Then it halves gap and repeats, down to gap = 1, which is plain
insertion sort, but on an array that is already nearly sorted.
- Time:
O(n²) with gaps n/2, n/4, …; better with other gap sequences - Space:
O(1) - Horowitz–Sahni, chapter 7
Eight mixed numbers: gaps 4, 2 and 1.
def shell_sort(a):gap = len(a) // 2while gap > 0:for j in range(gap, len(a)):key = a[j]i = j - gapwhile i >= 0:if a[i] <= key:breaka[i + gap] = a[i]i = i - gapa[i + gap] = keygap = gap // 2return a
Start
Local variables
Orange = changed in this step
a list
Call stack
- shell_sort()line 1
How the work grows with input size
Average of 12 random graphs per n (fixed seeds). Hollow marker = the input on screen.
- comparisons
- shift
- insert
- current input (n=8)
Show as a table
| n | comparisons | shift | insert |
|---|---|---|---|
| 4 | 6 | 2.8 | 5 |
| 6 | 11.6 | 5.9 | 8 |
| 8 | 21.1 | 7 | 17 |
| 10 | 29.1 | 11.3 | 22 |
| 12 | 37.8 | 16.7 | 26 |
| 14 | 44 | 19.4 | 31 |
| 16 | 68.7 | 26.8 | 49 |
Explanation
The idea
Insertion sort is very fast on a nearly sorted array, but an item far from its place has to walk there one position
at a time. Shell sort fixes this with a gap: first it insertion-sorts the items that are gap positions apart, so
items reach their rough place in long jumps. Then it halves gap and repeats, down to gap = 1, which is plain
insertion sort, but on an array that is already nearly sorted.
Cost
- With the gaps
n/2, n/4, …, 1the worst case isO(n²), but in practice it does much better than insertion sort. - With better sequences (for example
1, 4, 13, 40, …) the time drops to aboutO(n^1.5). - Extra memory
O(1); it is not stable.
What to watch in the trace
- Use the "every loop round" detail level to see only the changes of
gap. - Compare the "sorted backwards" input with insertion sort on the same input (the number of
shiftsteps).