Shivers Sort

Adaptive run-stack merge strategy related to practical natural-merge hybrids.

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

How it works

Adaptive run-stack merge strategy related to practical natural-merge hybrids.

Implementation

function shiversSort(arr, stats) {
  const n = arr.length;
  const runs = [];
  let i = 0;
  while (i < n) {
    let j = i + 1;
    while (j < n && arr[j - 1] <= arr[j]) {
      compare(j - 1, j);
      j++;
    }
    runs.push([i, j]);
    i = j;
  }
  const temp = new Array(n);
  function merge(a, b) {
    const lo = runs[a][0];
    const mid = runs[a][1];
    const hi = runs[b][1];
    let i1 = lo;
    let i2 = mid;
    let k = lo;
    while (i1 < mid && i2 < hi) {
      compare(i1, i2);
      if (arr[i1] <= arr[i2]) temp[k++] = arr[i1++]; else temp[k++] = arr[i2++];
    }
    while (i1 < mid) temp[k++] = arr[i1++];
    while (i2 < hi) temp[k++] = arr[i2++];
    for (let p = lo; p < hi; p++) {
      arr[p] = temp[p];
      write(p, arr[p]);
    }
    runs[a] = [lo, hi];
    runs.splice(b, 1);
  }
  while (runs.length > 1) {
    let merged = false;
    for (let r = 0; r + 2 < runs.length; r++) {
      const a = runs[r][1] - runs[r][0];
      const b = runs[r + 1][1] - runs[r + 1][0];
      const c = runs[r + 2][1] - runs[r + 2][0];
      if (a <= b + c) {
        merge(r, r + 1);
        merged = true;
        break;
      }
    }
    if (!merged) merge(runs.length - 2, runs.length - 1);
  }
}