How it works
Quicksort that preserves the order of equal elements by partitioning each range into less / equal / greater buffers and writing them straight back, so every level visibly regroups the bars in place. The equal block lands in its final position immediately.
Implementation
function stableQuickSort(arr, stats) { function sortRange(input) { if (input.length <= 1) return input; const pivot = input[input.length >> 1]; const less = []; const equal = []; const greater = []; for (let i = 0; i < input.length; i++) { if (input[i] < pivot) less.push(input[i]); else if (input[i] > pivot) greater.push(input[i]); else equal.push(input[i]); } return sortRange(less).concat(equal, sortRange(greater)); } 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): if (len(input) <= 1): return input pivot = input[(len(input) >> 1)] less = [] equal = [] greater = [] for i in range(len(input)): if (input[i] < pivot): less.append(input[i]) elif (input[i] > pivot): greater.append(input[i]) else: equal.append(input[i]) return sortRange(less) + equal + sortRange(greater) out = sortRange(arr[:]) for i in range(len(out)): arr[i] = out[i]
#include <vector> #include <algorithm> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { int sortRange(int input) { if((n <= 1)) { return input; } int pivot = input[(n >> 1)]; int less = {}; int equal = {}; int greater = {}; for(int i=0; (i < n); i++) { if((input[i] < pivot)) { less[less_len++] = input[i]; } else if((input[i] > pivot)) { greater[greater_len++] = input[i]; } else { equal[equal_len++] = input[i]; } } return sortRange(less)_concat(equal, sortRange(greater)); } 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) { if((n <= 1)) { return input; } int pivot = input[(n >> 1)]; int less = {}; int equal = {}; int greater = {}; for(int i=0; (i < n); i++) { if((input[i] < pivot)) { less[less_len++] = input[i]; } else if((input[i] > pivot)) { greater[greater_len++] = input[i]; } else { equal[equal_len++] = input[i]; } } return sortRange(less)_concat(equal, sortRange(greater)); } int out = sortRange(arr_slice); for(int i=0; (i < n); i++) { arr[i] = out[i]; } }
#include <stdio.h> void sort(int arr[], int n, int* comparisons, int* swaps) { int sortRange(int input) { if((n <= 1)) { return input; } int pivot = input[(n >> 1)]; int less = {}; int equal = {}; int greater = {}; for(int i=0; (i < n); i++) { if((input[i] < pivot)) { less[less_len++] = input[i]; } else if((input[i] > pivot)) { greater[greater_len++] = input[i]; } else { equal[equal_len++] = input[i]; } } return sortRange(less)_concat(equal, sortRange(greater)); } int out = sortRange(arr_slice); for(int i=0; (i < n); i++) { arr[i] = out[i]; } }