Natural Merge Sort

Adaptive merge sort that detects already ordered runs and merges them.

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 merge sort that detects already ordered runs and merges them.

Implementation

function naturalMergeSort(arr, stats) {
  const n = arr.length;
  const temp = new Array(n);
  function merge(lo, mid, hi) {
    let i = lo;
    let j = mid;
    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]);
    }
  }
  if (n < 2) return;
  let changed = true;
  while (changed) {
    changed = false;
    let start = 0;
    while (start < n) {
      let mid = start + 1;
      while (mid < n && arr[mid - 1] <= arr[mid]) {
        compare(mid - 1, mid);
        mid++;
      }
      if (mid >= n) break;
      let end = mid + 1;
      while (end < n && arr[end - 1] <= arr[end]) {
        compare(end - 1, end);
        end++;
      }
      merge(start, mid, end);
      changed = true;
      start = end;
    }
  }
}