Circle Sort

Compares elements equidistant from both ends, swapping if out of order. Repeats until no swaps needed. Simple and elegant.

Best O(n log n) Avg O(n log n log n) Worst O(n log n log n) Space O(log n) Stable No In-place Yes Comparison-based

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);
}