How it works
Compares elements equidistant from both ends, swapping if out of order. Repeats until no swaps needed. Simple and elegant.
Implementation
function circleSort(arr, stats) { const n = arr.length; if (n <= 1) return; function circlePass(lo, hi) { if (lo >= hi) return false; let swapped = false; let l = lo; let r = hi; while (l < r) { compare(l, r); if (arr[l] > arr[r]) { swap(l, r); let tmp = arr[l]; arr[l] = arr[r]; arr[r] = tmp; swapped = true; } l++; r--; } if (l === r && l + 1 < n) { compare(l, l + 1); if (arr[l] > arr[l + 1]) { swap(l, l + 1); let tmp = arr[l]; arr[l] = arr[l + 1]; arr[l + 1] = tmp; swapped = true; } } const mid = lo + Math.floor((hi - lo) / 2); const left = circlePass(lo, mid); const right = circlePass(mid + 1, hi); return swapped || left || right; } let iter = 0; let didSwap = circlePass(0, n - 1); while (didSwap) { iter++; checkpoint(iter, iter + 5); didSwap = circlePass(0, n - 1); } for (let i = 0; i < n; i++) markSorted(i); }
def circleSort(arr, stats): def circlePass(lo, hi): if (lo >= hi): return False swapped = False l = lo r = hi while (l < r): compare(l, r) if (arr[l] > arr[r]): swap(l, r) arr[l], arr[r] = arr[r], arr[l] swapped = True l += 1 r -= 1 if ((l == r) and ((l + 1) < n)): compare(l, (l + 1)) if (arr[l] > arr[(l + 1)]): swap(l, (l + 1)) arr[l], arr[(l + 1)] = arr[(l + 1)], arr[l] swapped = True mid = (lo + ((hi - lo) // 2)) left = circlePass(lo, mid) right = circlePass((mid + 1), hi) return ((swapped or left) or right) if (n <= 1): return iter = 0 didSwap = circlePass(0, (n - 1)) while didSwap: iter += 1 checkpoint(iter, (iter + 5)) didSwap = circlePass(0, (n - 1)) for i in range(n): markSorted(i)
#include <vector> #include <algorithm> int circlePass(int lo, int hi); int circlePass(int lo, int hi) { if((lo >= hi)) { return 0; } int swapped = 0; int l = lo; int r = hi; while((l < r)) { compare(l, r); if((arr[l] > arr[r])) { swap(l, r); std::swap(arr[l], arr[r]); swapped = 1; } l++; r--; } if(((l == r) && ((l + 1) < n))) { compare(l, (l + 1)); if((arr[l] > arr[(l + 1)])) { swap(l, (l + 1)); std::swap(arr[l], arr[(l + 1)]); swapped = 1; } } int mid = (lo + ((hi - lo) / 2)); int left = circlePass(lo, mid); int right = circlePass((mid + 1), hi); return ((((swapped) != 0 ? (swapped) : (left))) != 0 ? (((swapped) != 0 ? (swapped) : (left))) : (right)); } void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { if((n <= 1)) { return; } int iter = 0; int didSwap = circlePass(0, (n - 1)); while(didSwap) { iter++; checkpoint(iter, (iter + 5)); didSwap = circlePass(0, (n - 1)); } for(int i=0; i<n; i++) { markSorted(i); } }
int circlePass(int lo, int hi) { if((lo >= hi)) { return false; } int swapped = false; int l = lo; int r = hi; while((l < r)) { compare(l, r); if((arr[l] > arr[r])) { swap(l, r); { int _t = arr[l]; arr[l] = arr[r]; arr[r] = _t; } swapped = true; } l++; r--; } if(((l == r) && ((l + 1) < n))) { compare(l, (l + 1)); if((arr[l] > arr[(l + 1)])) { swap(l, (l + 1)); { int _t = arr[l]; arr[l] = arr[(l + 1)]; arr[(l + 1)] = _t; } swapped = true; } } int mid = (lo + ((hi - lo) / 2)); int left = circlePass(lo, mid); int right = circlePass((mid + 1), hi); return ((((swapped) != 0 ? (swapped) : (left))) != 0 ? (((swapped) != 0 ? (swapped) : (left))) : (right)); } public void Sort(int[] arr, int n, dynamic stats) { if((n <= 1)) { return; } int iter = 0; int didSwap = circlePass(0, (n - 1)); while(didSwap) { iter++; checkpoint(iter, (iter + 5)); didSwap = circlePass(0, (n - 1)); } for(int i=0; i<n; i++) { markSorted(i); } }
#include <stdio.h> int circlePass(int lo, int hi); int circlePass(int lo, int hi) { if((lo >= hi)) { return 0; } int swapped = 0; int l = lo; int r = hi; while((l < r)) { compare(l, r); if((arr[l] > arr[r])) { swap(l, r); { int _t = arr[l]; arr[l] = arr[r]; arr[r] = _t; } swapped = 1; } l++; r--; } if(((l == r) && ((l + 1) < n))) { compare(l, (l + 1)); if((arr[l] > arr[(l + 1)])) { swap(l, (l + 1)); { int _t = arr[l]; arr[l] = arr[(l + 1)]; arr[(l + 1)] = _t; } swapped = 1; } } int mid = (lo + ((hi - lo) / 2)); int left = circlePass(lo, mid); int right = circlePass((mid + 1), hi); return ((((swapped) != 0 ? (swapped) : (left))) != 0 ? (((swapped) != 0 ? (swapped) : (left))) : (right)); } void sort(int arr[], int n, int* comparisons, int* swaps) { if((n <= 1)) { return; } int iter = 0; int didSwap = circlePass(0, (n - 1)); while(didSwap) { iter++; checkpoint(iter, (iter + 5)); didSwap = circlePass(0, (n - 1)); } for(int i=0; i<n; i++) { markSorted(i); } }