Repeatedly removing the first two maximal initial runs and appending their sorted merge uses total fresh output cells in the worst case if obsolete cells are never reused. Group merges into rounds that consume the runs present at the start: the run count is at least halved up to rounding, and each round writes at most values. A tight-order family consists of copies of : run boundaries never coalesce and every merging level writes entries. Its final append-only endpoint is exactly .
Maximal initial run 2026-10-31
The longest nondecreasing prefix of a specified segment. For a nonempty segment , its endpoint is the first with and , or if no such descent exists. Scanning adjacent pairs takes time proportional to the returned run length. An empty segment has an empty maximal initial run.
Return the exclusive endpoint of the maximal initial run:
PROCEDURE Run(a, b: INTEGER): INTEGER;
VAR c: INTEGER;
BEGIN
  IF a = b THEN RETURN b END;
  c := a+1;
  WHILE c < b DO
    IF u[c-1] > u[c] THEN RETURN c END;
    c := c+1
  END;
  RETURN c
END Run;
The loop invariant is and is nondecreasing. An unsuccessful adjacent-order test extends the run by one; a strict descent at prevents any extension across it. If , the whole segment is a run. The loop variant is .
For a run of length , the running time is , including at most one failed extension test; an empty segment takes .
Let be the original sequence and . The loop invariant is
Here denotes the multiset of entries. The capacity condition uses the question's assumption of sufficient space. Removing two runs of combined length and appending their merge preserves the length and multiset. It also leaves all live values in one contiguous segment.
For a nonempty live sequence, let be its number of maximal initial runs obtained by repeatedly cutting at strict adjacent descents. The loop variant is . If x = d, there is one run and the procedure returns a sorted permutation. Otherwise the iteration removes two runs and appends one; it cannot create a new descent inside that appended run. The appended run may join the last old run, further reducing , so decreases by at least one. There are at most merges.
For , the loop is skipped and the empty segment is already sorted. No global stability claim is needed: moving a merged run behind other runs can change the order of equal-labelled occurrences.