How it works
Uses two pivots to partition into three segments. Used by Java Arrays.sort() for primitives. Fewer swaps on average.
Implementation
function dualPivotQuickSort(arr, stats) { const n = arr.length; const sorted = new Set(); function swap(i, j) { if (i === j) return; swap(i, j, { sorted }); const t = arr[i]; arr[i] = arr[j]; arr[j] = t; } function sort(lo, hi) { if (lo >= hi) { if (lo >= 0 && lo < n) markSorted(lo); return; } compare(lo, hi, { sorted }); if (arr[lo] > arr[hi]) swap(lo, hi); const p = arr[lo], q = arr[hi]; let lt = lo + 1, gt = hi - 1, k = lt; while (k <= gt) { compare(k, lo, { special: [lo, hi], sorted }); if (arr[k] < p) { swap(k, lt); lt++; } else if (arr[k] > q) { while (arr[gt] > q && k < gt) { gt--; } swap(k, gt); gt--; if (arr[k] < p) { swap(k, lt); lt++; } } k++; } lt--; gt++; swap(lo, lt); swap(hi, gt); markSorted(lt); markSorted(gt); sort(lo, lt - 1); sort(lt + 1, gt - 1); sort(gt + 1, hi); checkpoint(sorted.size, n); } sort(0, n - 1); }
from types import SimpleNamespace def dualPivotQuickSort(arr, stats): def swap(i, j): if (i == j): return swap(i, j, SimpleNamespace(sorted=sorted)) t = arr[i] arr[i] = arr[j] arr[j] = t def sort(lo, hi): if (lo >= hi): if ((lo >= 0) and (lo < n)): markSorted(lo) return compare(lo, hi, SimpleNamespace(sorted=sorted)) if (arr[lo] > arr[hi]): swap(lo, hi) p = arr[lo] q = arr[hi] lt = (lo + 1) gt = (hi - 1) k = lt while (k <= gt): compare(k, lo, SimpleNamespace(special=[lo, hi], sorted=sorted)) if (arr[k] < p): swap(k, lt) lt += 1 elif (arr[k] > q): while ((arr[gt] > q) and (k < gt)): gt -= 1 swap(k, gt) gt -= 1 if (arr[k] < p): swap(k, lt) lt += 1 k += 1 lt -= 1 gt += 1 swap(lo, lt) swap(hi, gt) markSorted(lt) markSorted(gt) sort(lo, (lt - 1)) sort((lt + 1), (gt - 1)) sort((gt + 1), hi) checkpoint(sorted.size, n) sorted = set() sort(0, (n - 1))
#include <vector> #include <algorithm> void swap(int i, int j); void sort(int lo, int hi); void swap(int i, int j) { if((i == j)) { return; } swap(i, j, {sorted: sorted}); int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void sort(int lo, int hi) { if((lo >= hi)) { if(((lo >= 0) && (lo < n))) { markSorted(lo); } return; } compare(lo, hi, {sorted: sorted}); if((arr[lo] > arr[hi])) { swap(lo, hi); } int p = arr[lo]; int q = arr[hi]; int lt = (lo + 1); int gt = (hi - 1); int k = lt; while((k <= gt)) { compare(k, lo, {special: {lo, hi}, sorted: sorted}); if((arr[k] < p)) { swap(k, lt); lt++; } else if((arr[k] > q)) { while(((arr[gt] > q) && (k < gt))) { gt--; } swap(k, gt); gt--; if((arr[k] < p)) { swap(k, lt); lt++; } } k++; } lt--; gt++; swap(lo, lt); swap(hi, gt); markSorted(lt); markSorted(gt); sort(lo, (lt - 1)); sort((lt + 1), (gt - 1)); sort((gt + 1), hi); checkpoint(sorted.size, n); } void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { int sorted = 0; sort(0, (n - 1)); }
void swap(int i, int j) { if((i == j)) { return; } swap(i, j, {sorted: sorted}); int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void sort(int lo, int hi) { if((lo >= hi)) { if(((lo >= 0) && (lo < n))) { markSorted(lo); } return; } compare(lo, hi, {sorted: sorted}); if((arr[lo] > arr[hi])) { swap(lo, hi); } int p = arr[lo]; int q = arr[hi]; int lt = (lo + 1); int gt = (hi - 1); int k = lt; while((k <= gt)) { compare(k, lo, {special: new int[] {lo, hi}, sorted: sorted}); if((arr[k] < p)) { swap(k, lt); lt++; } else if((arr[k] > q)) { while(((arr[gt] > q) && (k < gt))) { gt--; } swap(k, gt); gt--; if((arr[k] < p)) { swap(k, lt); lt++; } } k++; } lt--; gt++; swap(lo, lt); swap(hi, gt); markSorted(lt); markSorted(gt); sort(lo, (lt - 1)); sort((lt + 1), (gt - 1)); sort((gt + 1), hi); checkpoint(sorted.size, n); } public void Sort(int[] arr, int n, dynamic stats) { int sorted = 0; sort(0, (n - 1)); }
#include <stdio.h> void swap(int i, int j); void sort(int lo, int hi); void swap(int i, int j) { if((i == j)) { return; } swap(i, j, {sorted: sorted}); int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } void sort(int lo, int hi) { if((lo >= hi)) { if(((lo >= 0) && (lo < n))) { markSorted(lo); } return; } compare(lo, hi, {sorted: sorted}); if((arr[lo] > arr[hi])) { swap(lo, hi); } int p = arr[lo]; int q = arr[hi]; int lt = (lo + 1); int gt = (hi - 1); int k = lt; while((k <= gt)) { compare(k, lo, {special: {lo, hi}, sorted: sorted}); if((arr[k] < p)) { swap(k, lt); lt++; } else if((arr[k] > q)) { while(((arr[gt] > q) && (k < gt))) { gt--; } swap(k, gt); gt--; if((arr[k] < p)) { swap(k, lt); lt++; } } k++; } lt--; gt++; swap(lo, lt); swap(hi, gt); markSorted(lt); markSorted(gt); sort(lo, (lt - 1)); sort((lt + 1), (gt - 1)); sort((gt + 1), hi); checkpoint(sorted.size, n); } void sort(int arr[], int n, int* comparisons, int* swaps) { int sorted = 0; sort(0, (n - 1)); }