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) {
  const n = arr.length;
  // Compare-exchange: route the smaller value to the lower index.
  function ce(i, j) {
    if (arr[i] > arr[j]) [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  // Merge a sorted run of length li at i with a sorted run of length lj at j.
  function merge(i, li, j, lj) {
    if (li < 1 || lj < 1) return;
    if (li === 1 && lj === 1) ce(i, j);
    else if (li === 1 && lj === 2) { ce(i, j + 1); ce(i, j); }
    else if (li === 2 && lj === 1) { ce(i, j); ce(i + 1, j); }
    else {
      const a = li >> 1;
      const b = (li & 1) ? (lj >> 1) : ((lj + 1) >> 1);
      merge(i, a, j, b);
      merge(i + a, li - a, j + b, lj - b);
      merge(i + a, li - a, j, b);
    }
  }
  function sort(i, len) {
    if (len < 2) return;
    const m = len >> 1;
    sort(i, m);
    sort(i + m, len - m);
    merge(i, m, i + m, len - m);
  }
  sort(0, n); // data-oblivious: the comparator schedule never depends on values
}