DSAIntermediate6 min readPart 11 of 16

Sorting Algorithms

Sorting is a building block for many other algorithms. Knowing the trade-offs between sorting algorithms (time, extra space and stability) is expected in interviews, even though you will usually call the built-in sort.

Can you explain sorting algorithms out loud?

I'm Alex. Read this, then I'll interview you on real problems and push on the parts you skip.

Time complexity comparisonCompare

AlgorithmBestAverageWorstSpaceStable
Bubble SortO(n)O(n²)O(n²)O(1)Yes
Merge SortO(n log n)O(n log n)O(n log n)O(n)Yes
Quick SortO(n log n)O(n log n)O(n²)O(log n)No
Heap SortO(n log n)O(n log n)O(n log n)O(1)No
Counting SortO(n + k)O(n + k)O(n + k)O(k)Yes

Merge sortHow it works

Split the array in half, sort each half recursively, then merge the two sorted halves. It is stable and always O(n log n), but it needs O(n) extra space for the merge.

%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","actorBkg":"#e7f5ff","actorBorder":"#1e1e1e","noteBkgColor":"#fff9db","noteBorderColor":"#1e1e1e"}}}%%
graph TD
  A["38 27 43 3 9 82 10"] --> B["38 27 43 3"]
  A --> C["9 82 10"]
  B --> D["38 27"]
  B --> E["43 3"]
  C --> F["9 82"]
  C --> G["10"]
  D --> H["27 38"]
  E --> I["3 43"]
  F --> J["9 82"]
  G --> K["10"]
  H --> L["3 27 38 43"]
  I --> L
  J --> M["9 10 82"]
  K --> M
  L --> N["3 9 10 27 38 43 82"]
  M --> N
  class A,B,C,D,E,F,G red
  class H,I,J,K yellow
  class L,M blue
  class N green
classDef orange fill:#ffd8a8,stroke:#1e1e1e,color:#1e1e1e
classDef blue fill:#a5d8ff,stroke:#1e1e1e,color:#1e1e1e
classDef green fill:#b2f2bb,stroke:#1e1e1e,color:#1e1e1e
classDef red fill:#ffc9c9,stroke:#1e1e1e,color:#1e1e1e
classDef violet fill:#d0bfff,stroke:#1e1e1e,color:#1e1e1e
classDef yellow fill:#ffec99,stroke:#1e1e1e,color:#1e1e1e
classDef grey fill:#e9ecef,stroke:#1e1e1e,color:#1e1e1e
DiagramSplit down to single elements, then merge back up in sorted order.
Merge sortTypeScript
function mergeSort(nums: number[]): number[] {
  if (nums.length <= 1) return nums;
  const mid = Math.floor(nums.length / 2);
  const left = mergeSort(nums.slice(0, mid));
  const right = mergeSort(nums.slice(mid));
  return merge(left, right);
}

function merge(a: number[], b: number[]): number[] {
  const result: number[] = [];
  let i = 0, j = 0;
  while (i < a.length && j < b.length) {
    if (a[i] <= b[j]) result.push(a[i++]);
    else result.push(b[j++]);
  }
  return result.concat(a.slice(i), b.slice(j));
}
TimeO(n log n)SpaceO(n)Stableyes

Quick sortHow it works

Pick a pivot, move everything smaller to its left and everything bigger to its right (this is called partitioning), then sort each side the same way. It sorts in place, using only O(log n) stack space, but bad pivots make it O(n²).

Partitioning around pivot 5

before72916350123456pivotaftersmallerbigger21356790123456The pivot is now in its final place. Recurse on each side.
Quick sort (Lomuto partition)TypeScript
function quickSort(nums: number[], lo = 0, hi = nums.length - 1): void {
  if (lo >= hi) return;
  const pivotIdx = partition(nums, lo, hi);
  quickSort(nums, lo, pivotIdx - 1);
  quickSort(nums, pivotIdx + 1, hi);
}

function partition(nums: number[], lo: number, hi: number): number {
  const pivot = nums[hi];
  let i = lo;
  for (let j = lo; j < hi; j++) {
    if (nums[j] < pivot) {
      [nums[i], nums[j]] = [nums[j], nums[i]];
      i++;
    }
  }
  [nums[i], nums[hi]] = [nums[hi], nums[i]];
  return i;
}
TimeO(n log n) average, O(n²) worstSpaceO(log n)Stableno

Which sort to useWhen to use

Merge sort

When stability matters, or when you need a guaranteed O(n log n).

Quick sort

The default for sorting in memory. Fastest in practice because it works on nearby memory (good cache use).

Heap sort

When you need O(1) extra space and do not need stability.

Counting / radix sort

When values are integers in a small, known range. O(n) time.

Built-in sort

In interviews, use nums.sort((a, b) => a - b) unless you are asked to write the sort yourself.

Common mistakesPitfalls

Mishandling duplicatesThe quick sort partition must handle values equal to the pivot correctly.
Confusing stabilityA stable sort keeps equal elements in order, which matters when sorting by several keys.
Merge sort when memory is tightIt needs O(n) extra space.
Ignoring the input shapeOn nearly sorted data, insertion sort (O(n) best case) beats quick sort.
Writing a sort nobody asked forUse the built-in sort unless the question is about sorting itself.

In the interviewIn the interview

Sorting is often the first step of a bigger solution. Always include its cost in your final complexity.

Frequently asked questionsFAQ

Which sorting algorithm should you use in practice?

The hybrid quicksort used by most standard libraries is the default, sorting in place with O(n log n) average time. For already-sorted or tiny inputs, insertion sort and Timsort's natural-run detection beat it, so choose based on data characteristics rather than a single theoretical curve.

What are the best and worst cases of quicksort?

Quicksort averages O(n log n) with randomized pivots, but poor pivot choice on already-sorted input degrades it to O(n^2). Library implementations avoid this with median-of-three or introsort, which switches to heapsort beyond a recursion bound, guaranteeing O(n log n) worst case.

When is counting sort better than comparison-based sorting?

Counting sort runs in O(n + k), where k is the value range, beating the O(n log n) lower bound of comparison sorts. It works only for integer keys with a bounded range, which is why it suits grades, ages, or small IDs and serves as a subroutine of radix sort.

Now explain sorting algorithms to me out loud

I'll give you interview problems and ask follow-ups, like a real interviewer.

Practice with Alex

Keep readingKeep reading

Ready to practice?

Reading is step one. Saying it out loud is step two.

Start a mock interview with Alex, get pushed on the parts you skip, and see your hiring signal right after.