Block Sort

Stable in-place merge sort: recursively sorts the two halves, then merges them without an auxiliary array by rotating out-of-order runs into position (a block-rotation merge).

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

How it works

Stable in-place merge sort: recursively sorts the two halves, then merges them without an auxiliary array by rotating out-of-order runs into position (a block-rotation merge).

Implementation

function blockSort(arr, stats) {
  const n = arr.length;
  function swap(i, j) {
    let t = arr[i];
    arr[i] = arr[j];
    arr[j] = t;
    swap(i, j);
  }
  function rotate(start, mid, end) {
    if (start === mid || mid === end) return;
    let next = mid;
    while (start !== next) {
      swap(start++, next++);
      if (next === end) next = mid; else if (start === mid) mid = next;
    }
  }
  function mergeInPlace(start, mid, end) {
    if (start >= mid || mid >= end) return;
    if (arr[mid - 1] <= arr[mid]) return;
    let left = start, right = mid;
    while (left < mid && right < end) {
      compare(left, right);
      if (arr[left] <= arr[right]) {
        left++;
      } else {
        let tempRight = right;
        while (tempRight < end) {
          if (arr[tempRight] >= arr[left]) break;
          tempRight++;
        }
        rotate(left, right, tempRight);
        left += tempRight - right;
        mid += tempRight - right;
        right = tempRight;
      }
    }
  }
  function sort(l, r) {
    if (r - l < 1) return;
    if (r - l === 1) {
      if (arr[l] > arr[r]) swap(l, r);
      return;
    }
    const m = l + Math.floor((r - l) / 2);
    sort(l, m);
    sort(m + 1, r);
    mergeInPlace(l, m + 1, r + 1);
  }
  sort(0, n - 1);
  for (let i = 0; i < n; i++) markSorted(i);
}