How it works
3-way quicksort over key symbols/characters, ideal for string-like keys.
Implementation
function multikeyQuickSort(arr, stats) { const records = arr.map((value, index) => ({ value, key: String(value), index })); function charCodeAtOrNegOne(s, d) { return d < s.length ? s.charCodeAt(d) : -1; } function sort(lo, hi, d) { if (lo >= hi) return; let lt = lo; let gt = hi; const pivot = charCodeAtOrNegOne(records[lo].key, d); let i = lo + 1; while (i <= gt) { const code = charCodeAtOrNegOne(records[i].key, d); if (code < pivot) { const t = records[lt]; records[lt] = records[i]; records[i] = t; lt++; i++; } else if (code > pivot) { const t = records[i]; records[i] = records[gt]; records[gt] = t; gt--; } else { i++; } } sort(lo, lt - 1, d); if (pivot >= 0) sort(lt, gt, d + 1); sort(gt + 1, hi, d); } if (records.length > 1) sort(0, records.length - 1, 0); for (let i = 0; i < records.length; i++) { arr[i] = records[i].value; write(i, arr[i]); } }
def sort(arr, n, stats): records = arr.map(# UNSUPPORTED: ArrowFunctionExpression) def charCodeAtOrNegOne(s, d): return (s.charCodeAt(d) if (d < len(s)) else -1) def sort(lo, hi, d): if (lo >= hi): return lt = lo gt = hi pivot = charCodeAtOrNegOne(records[lo].key, d) i = (lo + 1) while (i <= gt): code = charCodeAtOrNegOne(records[i].key, d) if (code < pivot): t = records[lt] records[lt] = records[i] records[i] = t lt += 1 i += 1 elif (code > pivot): t = records[i] records[i] = records[gt] records[gt] = t gt -= 1 else: i += 1 sort(lo, (lt - 1), d) if (pivot >= 0): sort(lt, gt, (d + 1)) sort((gt + 1), hi, d) if (len(records) > 1): sort(0, (len(records) - 1), 0) for i in range(len(records)): arr[i] = records[i].value
#include <vector> #include <algorithm> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { int charCodeAtOrNegOne(int s, int d) { return (((d < n)) ? (s_charCodeAt(d)) : (-1)); } void sort(int lo, int hi, int d) { if((lo >= hi)) { return; } int lt = lo; int gt = hi; int pivot = charCodeAtOrNegOne(records[lo].key, d); int i = (lo + 1); while((i <= gt)) { int code = charCodeAtOrNegOne(records[i].key, d); if((code < pivot)) { int t = records[lt]; records[lt] = records[i]; records[i] = t; lt++; i++; } else if((code > pivot)) { int t = records[i]; records[i] = records[gt]; records[gt] = t; gt--; } else { i++; } } sort(lo, (lt - 1), d); if((pivot >= 0)) { sort(lt, gt, (d + 1)); } sort((gt + 1), hi, d); } int records = arr_map(/* UNSUPPORTED: ArrowFunctionExpression */); if((n > 1)) { sort(0, (n - 1), 0); } for(int i=0; (i < n); i++) { arr[i] = records[i].value; } }
public void Sort(int[] arr, int n, dynamic stats) { int charCodeAtOrNegOne(int s, int d) { return (((d < n)) ? (s_charCodeAt(d)) : (-1)); } void sort(int lo, int hi, int d) { if((lo >= hi)) { return; } int lt = lo; int gt = hi; int pivot = charCodeAtOrNegOne(records[lo].key, d); int i = (lo + 1); while((i <= gt)) { int code = charCodeAtOrNegOne(records[i].key, d); if((code < pivot)) { int t = records[lt]; records[lt] = records[i]; records[i] = t; lt++; i++; } else if((code > pivot)) { int t = records[i]; records[i] = records[gt]; records[gt] = t; gt--; } else { i++; } } sort(lo, (lt - 1), d); if((pivot >= 0)) { sort(lt, gt, (d + 1)); } sort((gt + 1), hi, d); } int records = arr_map(/* UNSUPPORTED: ArrowFunctionExpression */); if((n > 1)) { sort(0, (n - 1), 0); } for(int i=0; (i < n); i++) { arr[i] = records[i].value; } }
#include <stdio.h> void sort(int arr[], int n, int* comparisons, int* swaps) { int charCodeAtOrNegOne(int s, int d) { return (((d < n)) ? (s_charCodeAt(d)) : (-1)); } void sort(int lo, int hi, int d) { if((lo >= hi)) { return; } int lt = lo; int gt = hi; int pivot = charCodeAtOrNegOne(records[lo].key, d); int i = (lo + 1); while((i <= gt)) { int code = charCodeAtOrNegOne(records[i].key, d); if((code < pivot)) { int t = records[lt]; records[lt] = records[i]; records[i] = t; lt++; i++; } else if((code > pivot)) { int t = records[i]; records[i] = records[gt]; records[gt] = t; gt--; } else { i++; } } sort(lo, (lt - 1), d); if((pivot >= 0)) { sort(lt, gt, (d + 1)); } sort((gt + 1), hi, d); } int records = arr_map(/* UNSUPPORTED: ArrowFunctionExpression */); if((n > 1)) { sort(0, (n - 1), 0); } for(int i=0; (i < n); i++) { arr[i] = records[i].value; } }