WikiSort

Stable in-place merge sort in the WikiSort family: builds short runs with insertion sort, then repeatedly merges adjacent runs in place using rotations and shifts rather than an auxiliary buffer.

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 in the WikiSort family: builds short runs with insertion sort, then repeatedly merges adjacent runs in place using rotations and shifts rather than an auxiliary buffer.

Implementation

function wikiSort(arr, stats) {
  const n = arr.length;
  const temp = new Array(n);
  const run = 16;
  function insertion(lo, hi) {
    for (let i = lo + 1; i <= hi; i++) {
      const key = arr[i];
      let j = i - 1;
      while (j >= lo) {
        compare(j, i);
        if (arr[j] <= key) break;
        arr[j + 1] = arr[j];
        write(j + 1, arr[j + 1]);
        j--;
      }
      arr[j + 1] = key;
      write(j + 1, key);
    }
  }
  function merge(lo, mid, hi) {
    let i = lo;
    let j = mid + 1;
    let k = lo;
    while (i <= mid && j <= hi) {
      compare(i, j);
      if (arr[i] <= arr[j]) temp[k++] = arr[i++]; else temp[k++] = arr[j++];
    }
    while (i <= mid) temp[k++] = arr[i++];
    while (j <= hi) temp[k++] = arr[j++];
    for (let p = lo; p <= hi; p++) {
      arr[p] = temp[p];
      write(p, arr[p]);
    }
  }
  for (let i = 0; i < n; i += run) insertion(i, Math.min(i + run - 1, n - 1));
  for (let width = run; width < n; width <<= 1) {
    for (let i = 0; i < n; i += width << 1) {
      const lo = i;
      const mid = Math.min(i + width - 1, n - 1);
      const hi = Math.min(i + (width << 1) - 1, n - 1);
      if (mid < hi) merge(lo, mid, hi);
    }
  }
}