Proofs: Natural merge sort
These are the human proofs of Natural merge sort, at full length.
Natural merge sort sorts the array stably full
This proof shows: correctness.
Tag each input item with its index. We say that a part is stably sorted when its keys are non-decreasing and, for equal keys, the tags are increasing.
Lemma 1 (the runs). After line L1, with for , and each part is stably sorted.
Proof. The scan adds the index to exactly when , then adds . So between two neighbouring bounds, for each , and the keys are non-decreasing. Nothing has moved yet, so the tags increase along each part.
Lemma 2 (the merge). If and are stably sorted, and each tag in the left part is less than each tag in the right part, then after MERGE the part holds the same items and is stably sorted. Nothing outside it changes.
Proof. This is the merge of merge sort. Its invariant is that holds the least items of the two parts in stably sorted order, where an item of the left part counts as less than an item of the right part with an equal key. A step takes the right head only if it is strictly less than the left head, and else the left head, so it takes the least remaining item in this order. The loop ends when one part is used up, and the rest of the other part is already in place or is copied in order. The tags of the left part are all less than those of the right part, so on equal keys the tags increase.
Theorem. NATURAL-MERGE-SORT stops, and after it holds the input items and is stably sorted.
Proof. If , then , the loop does not run, and the empty array is sorted. Let . We use this invariant before each test of line L2:
with , holds the input items, each part is stably sorted, and each tag in a part is less than each tag in each later part.
By Lemma 1 it holds at the start, since the parts are the runs in input order and nothing has moved. Assume it before a pass with . For , line L5 merges the parts and , which are neighbours with the tags of the first less than the tags of the second. By Lemma 2 the merged part is stably sorted and holds the same items. Its tags are those of the two parts, so they are still less than the tags of all later parts and larger than the tags of all earlier parts. If is odd, the last part does not change. Line L6 and line L7 put into exactly the bounds of the new parts, ending with . So the invariant holds for , which has entries. Since for , the number of parts falls in each pass, and the loop stops with . Then is one part, which is stably sorted.