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) { function sortRange(input) { const n = input.length; if (n <= 32) { for (let i = 1; i < n; i++) { const key = input[i]; let j = i - 1; while (j >= 0) { if (input[j] <= key) break; input[j + 1] = input[j]; j--; } input[j + 1] = key; } return input; } const sampleCount = Math.max(3, Math.min(15, Math.floor(Math.sqrt(n)))); const step = Math.max(1, Math.floor(n / sampleCount)); const samples = []; for (let i = 0; i < n && samples.length < sampleCount; i += step) samples.push(input[i]); samples.sort((a, b) => a - b); const buckets = new Array(samples.length + 1).fill(null).map(() => []); for (const value of input) { let bi = 0; while (bi < samples.length) { if (value < samples[bi]) break; bi++; } buckets[bi].push(value); } const out = []; for (const bucket of buckets) { const sorted = sortRange(bucket); for (const v of sorted) out.push(v); } return out; } const out = sortRange(arr.slice()); for (let i = 0; i < out.length; i++) { arr[i] = out[i]; write(i, arr[i]); } }
def sort(arr, n, stats): def sortRange(input): n = len(input) if (n <= 32): for i in range(1, n): key = input[i] j = (i - 1) while (j >= 0): if (input[j] <= key): break input[(j + 1)] = input[j] j -= 1 input[(j + 1)] = key return input sampleCount = max(3, min(15, int(int(n ** 0.5)))) step = max(1, (n // sampleCount)) samples = [] i = 0 while ((i < n) and (len(samples) < sampleCount)): samples.append(input[i]) i += step samples.sort(# UNSUPPORTED: ArrowFunctionExpression) buckets = [0] * (len(samples) + 1).fill(None).map(# UNSUPPORTED: ArrowFunctionExpression) for value in input: bi = 0 while (bi < len(samples)): if (value < samples[bi]): break bi += 1 buckets[bi].append(value) out = [] for bucket in buckets: sorted = sortRange(bucket) for v in sorted: out.append(v) return out out = sortRange(arr[:]) for i in range(len(out)): arr[i] = out[i]
#include <vector> #include <algorithm> #include <cmath> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { int sortRange(int input) { int n = n; if((n <= 32)) { for(int i=1; (i < n); i++) { int key = input[i]; int j = (i - 1); while((j >= 0)) { if((input[j] <= key)) { break; } input[(j + 1)] = input[j]; j--; } input[(j + 1)] = key; } return input; } int sampleCount = ((3) > (((15) < ((int)std::floor((int)std::sqrt(n))) ? (15) : ((int)std::floor((int)std::sqrt(n))))) ? (3) : (((15) < ((int)std::floor((int)std::sqrt(n))) ? (15) : ((int)std::floor((int)std::sqrt(n)))))); int step = ((1) > ((n / sampleCount)) ? (1) : ((n / sampleCount))); int samples = {}; for(int i=0; ((i < n) && (n < sampleCount)); i += step) { samples[samples_len++] = input[i]; } samples_sort(/* UNSUPPORTED: ArrowFunctionExpression */); int buckets = _new_arr_(n + 1)_fill(0)_map(/* UNSUPPORTED: ArrowFunctionExpression */); /* for-of not directly supported in C */ int out = {}; /* for-of not directly supported in C */ return out; } int out = sortRange(arr_slice); for(int i=0; (i < n); i++) { arr[i] = out[i]; } }
public void Sort(int[] arr, int n, dynamic stats) { int sortRange(int input) { int n = n; if((n <= 32)) { for(int i=1; (i < n); i++) { int key = input[i]; int j = (i - 1); while((j >= 0)) { if((input[j] <= key)) { break; } input[(j + 1)] = input[j]; j--; } input[(j + 1)] = key; } return input; } int sampleCount = ((3) > (((15) < ((int)Math.Floor((int)Math.Sqrt(n))) ? (15) : ((int)Math.Floor((int)Math.Sqrt(n))))) ? (3) : (((15) < ((int)Math.Floor((int)Math.Sqrt(n))) ? (15) : ((int)Math.Floor((int)Math.Sqrt(n)))))); int step = ((1) > ((n / sampleCount)) ? (1) : ((n / sampleCount))); int samples = {}; for(int i=0; ((i < n) && (n < sampleCount)); i += step) { samples[samples_len++] = input[i]; } samples_sort(/* UNSUPPORTED: ArrowFunctionExpression */); int buckets = _new_arr_(n + 1)_fill(0)_map(/* UNSUPPORTED: ArrowFunctionExpression */); /* for-of not directly supported in C */ int out = {}; /* for-of not directly supported in C */ return out; } int out = sortRange(arr_slice); for(int i=0; (i < n); i++) { arr[i] = out[i]; } }
#include <stdio.h> #include <math.h> void sort(int arr[], int n, int* comparisons, int* swaps) { int sortRange(int input) { int n = n; if((n <= 32)) { for(int i=1; (i < n); i++) { int key = input[i]; int j = (i - 1); while((j >= 0)) { if((input[j] <= key)) { break; } input[(j + 1)] = input[j]; j--; } input[(j + 1)] = key; } return input; } int sampleCount = ((3) > (((15) < ((int)floor((int)sqrt(n))) ? (15) : ((int)floor((int)sqrt(n))))) ? (3) : (((15) < ((int)floor((int)sqrt(n))) ? (15) : ((int)floor((int)sqrt(n)))))); int step = ((1) > ((n / sampleCount)) ? (1) : ((n / sampleCount))); int samples = {}; for(int i=0; ((i < n) && (n < sampleCount)); i += step) { samples[samples_len++] = input[i]; } samples_sort(/* UNSUPPORTED: ArrowFunctionExpression */); int buckets = _new_arr_(n + 1)_fill(0)_map(/* UNSUPPORTED: ArrowFunctionExpression */); /* for-of not directly supported in C */ int out = {}; /* for-of not directly supported in C */ return out; } int out = sortRange(arr_slice); for(int i=0; (i < n); i++) { arr[i] = out[i]; } }