All eight sorting algorithms run on the same array below. We count the real work each one does — element comparisons and array writes — so you can see not just the Big-O on paper but how they actually behave on random, nearly-sorted, reversed, and few-unique data. Change the size and distribution to watch the ranking shift, then read which to use and why.
🔢On 50 random values, Counting Sort does the least work — 50 operations (0 comparisons + 50 writes).
| # | Algorithm | Comparisons | Writes | Total ops | Relative work |
|---|---|---|---|---|---|
| 🥇 | 🔢Counting SortO(n + k) | 0 | 50 | 50 | |
| 🥈 | 🧮Radix SortO(n·k) | 0 | 100 | 100 | |
| 🥉 | 🔀Merge SortO(n log n) | 226 | 286 | 512 | |
| 4 | ⚡Quick SortO(n log n) | 308 | 268 | 576 | |
| 5 | ⛰️Heap SortO(n log n) | 422 | 490 | 912 | |
| 6 | 📥Insertion SortO(n²) | 609 | 613 | 1,222 | |
| 7 | 🎯Selection SortO(n²) | 1,225 | 92 | 1,317 | |
| 8 | 🫧Bubble SortO(n²) | 1,219 | 1,128 | 2,347 |
“Operations” = element comparisons + array writes on the identical input above. Counts are exact and deterministic; wall-clock time depends on language, machine, and constant factors not captured here.
⚡ Default in-memory sort → Quick Sort
Best average-case speed with tiny constants and in-place O(log n) memory. It is what most language runtimes use (often as part of an introsort) for arrays of primitives. Watch it lose on the Reversed distribution — a naive last-element pivot degrades to O(n²).
🔀 Need stability or guaranteed O(n log n) → Merge Sort
Never worse than O(n log n) and stable (equal keys keep their order), which matters when sorting records by a secondary field. The cost is O(n) extra memory, so it shines for linked lists and huge on-disk (external) sorts.
⛰️ Tight memory, no worst-case risk → Heap Sort
In-place and guaranteed O(n log n) even in the worst case — no pathological input like Quick Sort. It is not stable and has poorer cache locality, so it is usually a bit slower in practice than Quick Sort.
📥 Small or nearly-sorted data → Insertion Sort
O(n) on nearly-sorted input (try the Nearly-sorted distribution — it often beats the O(n log n) sorts here) and extremely low overhead. Standard libraries switch to it for tiny subarrays inside Quick/Merge sort.
🔢 Small integer range → Counting / Radix Sort
Non-comparison sorts that break the O(n log n) comparison lower bound. Counting Sort is O(n + k) for values in a small range k; Radix Sort is O(n·d) for d-digit integers. Unbeatable for things like ages, ports, or fixed-width IDs — useless for arbitrary objects.
🎓 Teaching only → Bubble / Selection Sort
Both are O(n²) and almost always the slowest here. Selection Sort minimizes writes (≤ n swaps) if writes are very expensive; Bubble Sort’s only merit is detecting an already-sorted array in one O(n) pass. Avoid in production.
Want the step-by-step animation and code for one of these? Browse all algorithms →