Skip to main content
← All posts

Shell Sort: Mechanism, Complexity Analysis & Interactive Visualizer

Md. Harun-Or-RoshidNov 5, 20269 min readArticle
Shell Sort: Mechanism, Complexity Analysis & Interactive Visualizer
Basic Sorting · Article 6 of 62

Shell Sort

Insertion Sort, but on widely-spaced sub-arrays first. The gap shrinks each pass until a final gap of 1 finishes a nearly-sorted array fast.

How it works

Shell Sort, invented by Donald Shell in 1959, was one of the first sub-quadratic sorts. It chooses a sequence of gaps g₁ > g₂ > ... > 1 and runs gapped insertion sorts in sequence.

  1. Pick a gap sequence (e.g., n/2, n/4, ..., 1, or Ciura's tuned [701, 301, 132, 57, 23, 10, 4, 1]).
  2. For each gap g, do an insertion sort where the "neighbor" of i is i − g.
  3. Continue with smaller gaps. The final pass with g = 1 is plain insertion sort, but the array is now almost sorted, so it runs close to linear.

Time complexity depends heavily on the gap sequence. With Ciura's sequence, empirical performance is near O(n log² n); theoretical worst-case bounds reach O(n^{4/3}) with Sedgewick gaps.

Complexity

Best time
O(n log n)
Average time
≈ O(n^{1.25})
Worst time
O(n^{4/3}) – O(n²)
Extra space
O(1)
Stable
No
In-place
Yes
Shell Sort is the simplest non-trivial sub-quadratic algorithm. It uses no recursion, no auxiliary memory, and beats O(n²) sorts on practical input — historically attractive for embedded code.

Interactive visualization

Pseudocode

procedure shellSort(A):
  gaps ← [701, 301, 132, 57, 23, 10, 4, 1]
  for gap in gaps where gap < n:
    for i from gap to n − 1:
      temp ← A[i]; j ← i
      while j ≥ gap and A[j − gap] > temp:
        A[j] ← A[j − gap]; j ← j − gap
      A[j] ← temp

JavaScript implementation

function shellSort(arr) {
  const gaps = [701, 301, 132, 57, 23, 10, 4, 1];
  for (const gap of gaps) {
    if (gap >= arr.length) continue;
    for (let i = gap; i < arr.length; i++) {
      const temp = arr[i];
      let j = i;
      while (j >= gap && arr[j - gap] > temp) {
        arr[j] = arr[j - gap]; j -= gap;
      }
      arr[j] = temp;
    }
  }
  return arr;
}

Pros and cons

Pros

  • Sub-quadratic without recursion or extra memory.
  • Simple, branchy code — friendly on embedded targets.
  • Adapts to the input: nearly-sorted runs are fast.
  • Open optimization space — different gap sequences trade analysis for speed.

Cons

  • Not stable.
  • Worst-case bound depends on gap sequence — and the optimal sequence is still an open problem.
  • Loses to merge/quick sort for large n.

When to use it

  • Embedded systems where binary size matters and you need better than O(n²).
  • Medium arrays (n < 10⁵) when simplicity is valued.
  • Avoiding recursion for stack-limited environments.
Up next: Merge Sort — an iterative version of Merge Sort with no recursion — same merges, just driven by doubling run sizes.
Share:
Share on X
Share on LinkedIn
Share on Facebook
Share on Reddit
Share on WhatsApp
Share on Telegram
Copy link

Related reading

Shell Sort Sorting Algorithm & Guide | Draftsbook · Draftsbook