How it works
Quicksort variant using block partitioning to reduce branch mispredictions.
Implementation
function blockQuickSort(arr, stats) { function swap(i, j) { if (i === j) return; swap(i, j); const t = arr[i]; arr[i] = arr[j]; arr[j] = t; } function compareAndMaybeSwap(i, j) { compare(i, j); if (arr[i] > arr[j]) swap(i, j); } function partition(lo, hi) { const mid = lo + hi >> 1; compareAndMaybeSwap(lo, mid); compareAndMaybeSwap(lo, hi); compareAndMaybeSwap(mid, hi); const pivot = arr[hi]; let store = lo; for (let i = lo; i < hi; i++) { compare(i, hi); if (arr[i] <= pivot) { swap(i, store); store++; } } swap(store, hi); return store; } if (arr.length < 2) return; const stack = [[0, arr.length - 1]]; while (stack.length) { const range = stack.pop(); let lo = range[0]; let hi = range[1]; while (lo < hi) { const p = partition(lo, hi); const leftSize = p - lo; const rightSize = hi - p; if (leftSize < rightSize) { if (p + 1 < hi) stack.push([p + 1, hi]); hi = p - 1; } else { if (lo < p - 1) stack.push([lo, p - 1]); lo = p + 1; } } } }
def sort(arr, n, stats): def swap(i, j): if (i == j): return t = arr[i] arr[i] = arr[j] arr[j] = t def compareAndMaybeSwap(i, j): if (arr[i] > arr[j]): swap(i, j) def partition(lo, hi): mid = ((lo + hi) >> 1) compareAndMaybeSwap(lo, mid) compareAndMaybeSwap(lo, hi) compareAndMaybeSwap(mid, hi) pivot = arr[hi] store = lo for i in range(lo, hi): if (arr[i] <= pivot): swap(i, store) store += 1 swap(store, hi) return store if (len(arr) < 2): return stack = [[0, (len(arr) - 1)]] while len(stack): range = stack.pop() lo = range[0] hi = range[1] while (lo < hi): p = partition(lo, hi) leftSize = (p - lo) rightSize = (hi - p) if (leftSize < rightSize): if ((p + 1) < hi): stack.append([(p + 1), hi]) hi = (p - 1) else: if (lo < (p - 1)): stack.append([lo, (p - 1)]) lo = (p + 1)
#include <vector> #include <algorithm> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { void swap(int i, int j) { if((i == j)) { return; } int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void compareAndMaybeSwap(int i, int j) { if((arr[i] > arr[j])) { swap(i, j); } } int partition(int lo, int hi) { int mid = ((lo + hi) >> 1); compareAndMaybeSwap(lo, mid); compareAndMaybeSwap(lo, hi); compareAndMaybeSwap(mid, hi); int pivot = arr[hi]; int store = lo; for(int i=lo; (i < hi); i++) { if((arr[i] <= pivot)) { swap(i, store); store++; } } swap(store, hi); return store; } if((n < 2)) { return; } int stack = {{0, (n - 1)}}; while(n) { int range = stack_pop(); int lo = range[0]; int hi = range[1]; while((lo < hi)) { int p = partition(lo, hi); int leftSize = (p - lo); int rightSize = (hi - p); if((leftSize < rightSize)) { if(((p + 1) < hi)) { stack[stack_len++] = {(p + 1), hi}; } hi = (p - 1); } else { if((lo < (p - 1))) { stack[stack_len++] = {lo, (p - 1)}; } lo = (p + 1); } } } }
public void Sort(int[] arr, int n, dynamic stats) { void swap(int i, int j) { if((i == j)) { return; } int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void compareAndMaybeSwap(int i, int j) { if((arr[i] > arr[j])) { swap(i, j); } } int partition(int lo, int hi) { int mid = ((lo + hi) >> 1); compareAndMaybeSwap(lo, mid); compareAndMaybeSwap(lo, hi); compareAndMaybeSwap(mid, hi); int pivot = arr[hi]; int store = lo; for(int i=lo; (i < hi); i++) { if((arr[i] <= pivot)) { swap(i, store); store++; } } swap(store, hi); return store; } if((n < 2)) { return; } int stack = {{0, (n - 1)}}; while(n) { int range = stack_pop(); int lo = range[0]; int hi = range[1]; while((lo < hi)) { int p = partition(lo, hi); int leftSize = (p - lo); int rightSize = (hi - p); if((leftSize < rightSize)) { if(((p + 1) < hi)) { stack[stack_len++] = {(p + 1), hi}; } hi = (p - 1); } else { if((lo < (p - 1))) { stack[stack_len++] = {lo, (p - 1)}; } lo = (p + 1); } } } }
#include <stdio.h> void sort(int arr[], int n, int* comparisons, int* swaps) { void swap(int i, int j) { if((i == j)) { return; } int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void compareAndMaybeSwap(int i, int j) { if((arr[i] > arr[j])) { swap(i, j); } } int partition(int lo, int hi) { int mid = ((lo + hi) >> 1); compareAndMaybeSwap(lo, mid); compareAndMaybeSwap(lo, hi); compareAndMaybeSwap(mid, hi); int pivot = arr[hi]; int store = lo; for(int i=lo; (i < hi); i++) { if((arr[i] <= pivot)) { swap(i, store); store++; } } swap(store, hi); return store; } if((n < 2)) { return; } int stack = {{0, (n - 1)}}; while(n) { int range = stack_pop(); int lo = range[0]; int hi = range[1]; while((lo < hi)) { int p = partition(lo, hi); int leftSize = (p - lo); int rightSize = (hi - p); if((leftSize < rightSize)) { if(((p + 1) < hi)) { stack[stack_len++] = {(p + 1), hi}; } hi = (p - 1); } else { if((lo < (p - 1))) { stack[stack_len++] = {lo, (p - 1)}; } lo = (p + 1); } } } }