Choosing a sorting algorithm is mostly a choice among guarantees. Stability preserves the input order of equal keys. Extra memory may buy predictable merges, while in-place partitioning usually improves locality. Key structure can remove the comparison bound entirely.

The input decides which tradeoff matters. Nearly sorted data favors adaptive algorithms, a small integer range can make counting sort linear, and strict memory limits narrow the field to in-place choices. The tables below keep those boundaries visible instead of treating one algorithm as a universal default.

Diagram

flowchart TD
  A[Need sorting] --> B{Keys are small integers or fixed width}
  B -->|Yes| B1{Key range is comparable to n}
  B1 -->|Yes| B2[Counting Sort]
  B1 -->|No but keys are fixed width| B3[Radix Sort]
  B1 -->|Keys spread uniformly over a range| B4[Bucket Sort]
  B -->|No, comparison sort needed| C{Need stable output}
  C -->|Yes| D{Need O n log n worst case}
  D -->|Yes| E[Merge Sort or Tim Sort]
  D -->|No| F[Insertion Sort only for small or nearly sorted input]
  C -->|No| G{Need in place and fast average case}
  G -->|Yes with worst case guarantee| H[Introsort]
  G -->|Yes| I[Quick Sort]
  G -->|No| J[Selection Sort or Bubble Sort for learning]

Algorithm Selection

Comparison Sorts — Worst-case lower bound Ω(n log n)

AlgorithmAverageWorstSpaceStableReach for it when
Bubble SortO(n²)O(n²)O(1)YesTeaching only
Cocktail Shaker SortO(n²)O(n²)O(1)YesTeaching bidirectional passes. Moves small tail values forward faster than Bubble Sort
Gnome SortO(n²)O(n²)O(1)YesTeaching inversion removal with one walking index
Bogo SortΘ(n · n!) expectedUnboundedO(1)NoBounded demonstrations only. Random retries make no progress guarantee
Comb SortEmpirically near O(n log n) on random input. Not guaranteedO(n²)O(1)NoTeaching why bubble sort is slow
Selection SortO(n²)O(n²)O(1)NoWrites are far costlier than reads
Cycle SortΘ(n²)Θ(n²)O(1)NoWrites are exceptionally expensive and keys can be compared cheaply
Insertion SortO(n²)O(n²)O(1)YesTiny or nearly-sorted input. Base case of hybrids
Odd-Even SortO(n²) sequentialO(n²) sequentialO(1)YesDisjoint neighbor phases will run in parallel. Otherwise teaching only
Pancake SortΘ(n²)Θ(n²)O(1)NoThe only permitted move is a prefix reversal
Stooge SortΘ(n².7095)Θ(n².7095)O(log n)NoRecurrence-analysis exercise only
Shell Sort~O(n^1.3)O(n^1.5) with HibbardO(1)NoNo recursion, no scratch memory (embedded)
Heap SortO(n log n)O(n log n)O(1)NoHard worst-case bound with no extra memory
Merge SortO(n log n)O(n log n)O(n)YesStability required. Linked lists. External sort
Quick SortO(n log n)O(n²)O(log n) expected, O(n) worstNoCache-friendly in-memory default
Tim SortO(n log n)O(n log n)O(n)YesReal-world partly-ordered data. Python lists and Java object arrays
IntrosortO(n log n)O(n log n)O(log n)NoQuicksort’s speed without its O(n²) tail (C++, .NET)

Non-comparison Sorts — Beat the Bound by Reading Key Structure

AlgorithmTimeSpaceStablePrecondition
Counting SortO(n + k)O(n + k)YesInteger keys in a small range [0, k)
Radix SortO(d · (n + b))O(n + b)YesFixed-width keys. Needs a stable inner sort
Bucket SortO(n + k) avg, O(n²) worstO(n + k)Depends. Stable with order-preserving scatter and stable per-bucket sortKeys roughly uniform over a known range

References

20 items under this folder.