Partition around a pivot so smaller values go left and larger go right, then recurse on both sides — O(n log n) average, in place.
Quick sort is the workhorse of in-memory sorting. Pick one value as the pivot, then partition the list so everything smaller sits left of it and everything larger sits right. The pivot is now in its final position — and you sort the two sides the same way. It's usually the fastest comparison sort in practice, sorting within the array itself.
Partitioning is what does the real work; the recursion just glues it together. In the common Lomuto scheme you pick the last element as pivot and sweep a pointer across, keeping a boundary i for 'everything left of here is smaller than the pivot'. Each value < pivot is swapped to the boundary. At the end you swap the pivot into the boundary slot — and it's home.
j across the range; whenever arr[j] < pivot, swap it to the boundary i and advance i.i — now everything left is smaller, everything right is larger.function quickSort(arr, lo = 0, hi = arr.length - 1) {
if (lo >= hi) return arr;
const pivot = arr[hi];
let i = lo;
for (let j = lo; j < hi; j++) {
if (arr[j] < pivot) { [arr[i], arr[j]] = [arr[j], arr[i]]; i++; }
}
[arr[i], arr[hi]] = [arr[hi], arr[i]]; // pivot to its final spot
quickSort(arr, lo, i - 1);
quickSort(arr, i + 1, hi);
return arr;
}n levels of O(n) work: O(n²). Picking a random pivot or the median-of-three makes that worst case astronomically unlikely.log n levels, each doing O(n) total work across all partitions on that level. The result is O(n log n) — and because it reorders in place, it's also very cache-friendly.