Sample Sort

Generalizes quicksort to many pivots: it draws a set of splitter samples, distributes each range into buckets between consecutive splitters, writes the buckets straight back, and recurses. Each level visibly regroups the bars into ordered buckets.

Best O(n) Avg O(n log n) Worst O(n log² n) Space O(n) Stable No In-place No Comparison-based

How it works

Generalizes quicksort to many pivots: it draws a set of splitter samples, distributes each range into buckets between consecutive splitters, writes the buckets straight back, and recurses. Each level visibly regroups the bars into ordered buckets.

Implementation

function sampleSort(arr, stats) {
  const n = arr.length;
  if (n < 2) return;
  const buckets = Math.max(2, Math.floor(Math.sqrt(n)));
  const splitters = new Array(buckets).fill(0);
  for (let s = 0; s < buckets - 1; s++) {
    const idx = Math.floor(((s + 1) * n) / buckets);
    splitters[s] = arr[idx];
  }
  for (let s = 1; s < buckets - 1; s++) {
    const key = splitters[s];
    let j = s - 1;
    while (j >= 0 && splitters[j] > key) {
      splitters[j + 1] = splitters[j];
      j--;
    }
    splitters[j + 1] = key;
  }
  const count = new Array(buckets).fill(0);
  const bucketOf = new Array(n).fill(0);
  for (let i = 0; i < n; i++) {
    let b = 0;
    while (b < buckets - 1 && arr[i] >= splitters[b]) {
      b++;
    }
    bucketOf[i] = b;
    count[b]++;
  }
  const offset = new Array(buckets).fill(0);
  let sum = 0;
  for (let b = 0; b < buckets; b++) {
    offset[b] = sum;
    sum = sum + count[b];
  }
  const temp = new Array(n).fill(0);
  const pos = new Array(buckets).fill(0);
  for (let b = 0; b < buckets; b++) {
    pos[b] = offset[b];
  }
  for (let i = 0; i < n; i++) {
    const b = bucketOf[i];
    temp[pos[b]] = arr[i];
    pos[b]++;
  }
  for (let i = 0; i < n; i++) {
    arr[i] = temp[i];
  }
  for (let b = 0; b < buckets; b++) {
    const lo = offset[b];
    const hi = offset[b] + count[b];
    for (let i = lo + 1; i < hi; i++) {
      const key = arr[i];
      let j = i - 1;
      while (j >= lo && arr[j] > key) {
        arr[j + 1] = arr[j];
        j--;
      }
      arr[j + 1] = key;
    }
  }
}