How it works
Like LSD Radix Sort but processes from the most significant digit first. Can short-circuit on already-sorted data.
Implementation
function radixMSDSort(arr, lo = 0, hi = arr.length-1, d) { if (d === undefined) d = Math.max(...arr).toString().length - 1; if (lo >= hi || d < 0) return; const exp = Math.pow(10, d); const bk = Array.from({length: 10}, () => []); for (let i = lo; i <= hi; i++) bk[Math.floor(arr[i] / exp) % 10].push(arr[i]); let idx = lo; for (let b = 0; b < 10; b++) { const start = idx; for (const v of bk[b]) arr[idx++] = v; if (bk[b].length > 1) radixMSDSort(arr, start, idx-1, d-1); } }
def radix_msd_sort(arr, lo=0, hi=None, d=None): if hi is None: hi = len(arr)-1 if d is None: d = len(str(max(arr)))-1 if lo >= hi or d < 0: return exp = 10 ** d bk = [[] for _ in range(10)] for i in range(lo, hi+1): bk[(arr[i]//exp) % 10].append(arr[i]) idx = lo for b in range(10): start = idx for v in bk[b]: arr[idx] = v; idx += 1 if len(bk[b]) > 1: radix_msd_sort(arr, start, idx-1, d-1)
void radixMSDSort(vector<int>& arr, int lo, int hi, int d) { if (lo >= hi || d < 0) return; int exp = (int)pow(10, d); vector<vector<int>> bk(10); for (int i = lo; i <= hi; i++) bk[(arr[i]/exp)%10].push_back(arr[i]); int idx = lo; for (int b = 0; b < 10; b++) { int start = idx; for (int v : bk[b]) arr[idx++] = v; if (bk[b].size() > 1) radixMSDSort(arr, start, idx-1, d-1); } }
void RadixMSDSort(int[] arr, int lo, int hi, int d) { if (lo >= hi || d < 0) return; int exp = (int)Math.Pow(10, d); var bk = Enumerable.Range(0,10) .Select(_ => new List<int>()).ToArray(); for (int i = lo; i <= hi; i++) bk[(arr[i]/exp) % 10].Add(arr[i]); int idx = lo; for (int b = 0; b < 10; b++) { int start = idx; foreach (int v in bk[b]) arr[idx++] = v; if (bk[b].Count > 1) RadixMSDSort(arr, start, idx-1, d-1); } }
void radixMSDSort(int arr[], int lo, int hi, int d) { if (lo >= hi || d < 0) return; int exp = 1; for (int i = 0; i < d; i++) exp *= 10; // Distribute into 10 buckets by digit d // Recurse on each bucket with d-1 }