Bose-Nelson Sort

A data-oblivious sorting network from Bose and Nelson (1962). A recursive merge schedule emits a fixed list of compare-exchanges that is correct for any array length, so it sorts in place with no extra buffers and a comparison pattern independent of the data.

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

How it works

A data-oblivious sorting network from Bose and Nelson (1962). A recursive merge schedule emits a fixed list of compare-exchanges that is correct for any array length, so it sorts in place with no extra buffers and a comparison pattern independent of the data.

Implementation

function boseNelsonSort(arr, stats) {
  const n = arr.length;
  if (n < 2) {
    if (n === 1) markSorted(0);
    return;
  }
  function compareExchange(i, j) {
    compare(i, j);
    if (arr[i] > arr[j]) {
      swap(i, j);
      const t = arr[i];
      arr[i] = arr[j];
      arr[j] = t;
    }
  }
  function merge(i, li, j, lj) {
    if (li < 1 || lj < 1) return;
    if (li === 1 && lj === 1) {
      compareExchange(i, j);
    } else if (li === 1 && lj === 2) {
      compareExchange(i, j + 1);
      compareExchange(i, j);
    } else if (li === 2 && lj === 1) {
      compareExchange(i, j);
      compareExchange(i + 1, j);
    } else {
      const imid = li >> 1;
      const jmid = (li & 1) === 1 ? lj >> 1 : lj + 1 >> 1;
      merge(i, imid, j, jmid);
      merge(i + imid, li - imid, j + jmid, lj - jmid);
      merge(i + imid, li - imid, j, jmid);
    }
  }
  function sort(i, length) {
    if (length < 2) return;
    const m = length >> 1;
    sort(i, m);
    sort(i + m, length - m);
    merge(i, m, i + m, length - m);
    checkpoint(i + length, n);
  }
  sort(0, n);
  for (let i = 0; i < n; i++) markSorted(i);
}