Shell Sort
O(n^1.3)

History

Shell Sort was invented by Donald Shell in 1959. It was one of the first algorithms to break the O(n²) barrier. The algorithm is a generalization of insertion sort that allows the exchange of items that are far apart, progressively reducing the gap between elements to compare. The efficiency depends heavily on the gap sequence used. Shell's original sequence gives O(n²), but better sequences can achieve O(n log² n) or better.

How it works

  1. Start with a large gap (typically n/2)
  2. Compare elements that are 'gap' positions apart
  3. Swap if they are in the wrong order
  4. Reduce the gap (typically by half)
  5. Repeat until gap becomes 1 (final insertion sort)

When to use

  • Medium-sized arrays: Good balance of simplicity and speed
  • Embedded systems: Low memory overhead, no recursion
  • When code size matters: Compact implementation
  • Partially sorted data: Adapts well to existing order

Implementation

def shell_sort(arr):
    n = len(arr)
    gap = n // 2
    while gap > 0:
        for i in range(gap, n):
            temp = arr[i]
            j = i
            while j >= gap and arr[j - gap] > temp:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap //= 2
    return arr
function shellSort(arr) {
    const n = arr.length;
    let gap = Math.floor(n / 2);
    while (gap > 0) {
        for (let i = gap; i < n; i++) {
            let temp = arr[i];
            let j = i;
            while (j >= gap && arr[j - gap] > temp) {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }
        gap = Math.floor(gap / 2);
    }
    return arr;
}
func shellSort(arr []int) []int {
    n := len(arr)
    gap := n / 2
    for gap > 0 {
        for i := gap; i < n; i++ {
            temp := arr[i]
            j := i
            for j >= gap && arr[j-gap] > temp {
                arr[j] = arr[j-gap]
                j -= gap
            }
            arr[j] = temp
        }
        gap /= 2
    }
    return arr
}
fn shell_sort<T: Ord + Copy>(arr: &mut [T]) {
    let n = arr.len();
    let mut gap = n / 2;
    while gap > 0 {
        for i in gap..n {
            let temp = arr[i];
            let mut j = i;
            while j >= gap && arr[j - gap] > temp {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }
        gap /= 2;
    }
}

Complexity

Best Case O(n log n)
Average Case O(n^1.3)
Worst Case O(n²)
Space O(1)
Stable No

Try it yourself

See this algorithm in action with the visualizer.

Run