Algorithm Search⌘K

Proofs: Counting inversions by merge sort

These are the human proofs of Counting inversions by merge sort, at full length.

Sort-and-Count returns the number of inversions and sorts the range full

This proof shows: correctness, termination.

We use the pseudocode of the page. For a range R=A[lo…hi−1]R = A[lo \ldots hi-1], write inv⁡(R)\operatorname{inv}(R) for the number of pairs of indices lo≤p<q<hilo \le p < q < hi with A[p]>A[q]A[p] > A[q], taken at the start of the call. For two finite multisets LL and MM of items, write χ(L,M)=∣{(x,y)∈L×M:x>y}∣\chi(L, M) = |\{(x, y) \in L \times M : x > y\}|, counting each copy of an item separately. χ(L,M)\chi(L, M) depends only on the two multisets, not on the order in which they are stored.

Split of the count. Let lo≤mid≤hilo \le mid \le hi, let LL be the multiset of A[lo…mid−1]A[lo \ldots mid-1] and MM the multiset of A[mid…hi−1]A[mid \ldots hi-1]. Each pair p<qp < q of the range has both indices below midmid, both indices at least midmid, or p<mid≤qp < mid \le q. The pairs of the third kind with A[p]>A[q]A[p] > A[q] are exactly the pairs of L×ML \times M with the first item larger. So

inv⁡(A[lo…hi−1])=inv⁡(A[lo…mid−1])+inv⁡(A[mid…hi−1])+χ(L,M).(1)\operatorname{inv}(A[lo \ldots hi-1]) = \operatorname{inv}(A[lo \ldots mid-1]) + \operatorname{inv}(A[mid \ldots hi-1]) + \chi(L, M). \tag{1}

Lemma (MERGE-AND-COUNT). Assume that lo≤mid≤hilo \le mid \le hi and that A[lo…mid−1]A[lo \ldots mid-1] and A[mid…hi−1]A[mid \ldots hi-1] are sorted, with multisets LL and MM. Then MERGE-AND-COUNT(A,lo,mid,hi)(A, lo, mid, hi) returns χ(L,M)\chi(L, M), leaves A[lo…hi−1]A[lo \ldots hi-1] sorted with the multiset L∪ML \cup M, and changes no other item of AA.

Proof. The data movement of lines L6 to L13 is the merge of merge sort, and the counter cc does not affect it. So the proof of the merge lemma on the merge sort page shows that the range ends sorted with the multiset L∪ML \cup M, that no other item changes, and that the write position kk never passes the read position jj. It remains to show what cc counts. Let m=∣B∣=mid−lom = |B| = mid - lo, and for j′∈[mid,hi)j' \in [mid, hi) write rj′r_{j'} for the item at index j′j' at the start of the call; these items are not changed before they are read. We use this invariant of the loop of line L8.

(C) c=∑j′=midj−1∣{t:0≤t<m, B[t]>rj′}∣c = \sum_{j' = mid}^{j - 1} |\{t : 0 \le t < m,\ B[t] > r_{j'}\}|, and each item of B[0…i−1]B[0 \ldots i-1] is at most each of rj,rj+1,…,rhi−1r_j, r_{j+1}, \ldots, r_{hi-1}.

Initialization. Line L7 sets c=0c = 0, j=midj = mid and i=0i = 0. The sum is empty and B[0…−1]B[0 \ldots -1] is empty, so (C) holds.

Maintenance. Assume (C) before a step of line L8, so i<mi < m and j<hij < hi.

  • If B[i]≤rjB[i] \le r_j, line L9 places B[i]B[i] and increases ii. The right half is sorted, so B[i]≤rj≤rj+1≤⋯B[i] \le r_j \le r_{j+1} \le \cdots, and the second part of (C) holds for i+1i + 1. The values cc and jj do not change, so the first part still holds.
  • If B[i]>rjB[i] > r_j, line L10 places rjr_j, adds m−im - i to cc, and increases jj. Since BB is sorted, B[t]≥B[i]>rjB[t] \ge B[i] > r_j for each t≥it \ge i, so at least m−im - i items of BB are larger than rjr_j. By the second part of (C), each B[t]B[t] with t<it < i is at most rjr_j. So exactly m−im - i items of BB are larger than rjr_j, and the new cc is the sum of (C) up to j′=jj' = j. The second part holds for the new jj, because rj+1,…r_{j+1}, \ldots are a subset of the old list.

Each step increases i+ji + j by exactly 1, and i+j≤m+hii + j \le m + hi, so the loop stops after at most m+(hi−mid)m + (hi - mid) steps.

Termination. The loop stops when i=mi = m or j=hij = hi.

  • If j=hij = hi, the first part of (C) is the sum over all right items, which is χ(L,M)\chi(L, M) because BB holds the multiset LL. The loop of line L12 only moves items and does not change cc.
  • If i=mi = m and j<hij < hi, the second part of (C) says that each item of BB is at most each of rj,…,rhi−1r_j, \ldots, r_{hi-1}. So these right items have no larger left item, and their terms of χ(L,M)\chi(L, M) are 0. The sum of (C) up to j−1j - 1 is then χ(L,M)\chi(L, M). The loop of line L12 does not run, since i=mi = m.

In both cases line L14 returns χ(L,M)\chi(L, M). □\square

Theorem. SORT-AND-COUNT(A,lo,hi)(A, lo, hi) returns inv⁡(A[lo…hi−1])\operatorname{inv}(A[lo \ldots hi-1]), leaves A[lo…hi−1]A[lo \ldots hi-1] sorted with the same multiset of items, changes no other item of AA, and terminates.

Proof. By strong induction on s=hi−los = hi - lo.

Base. If s≤1s \le 1, the range has no pair of indices, so its inversion count is 0. Line L1 returns 0 and changes nothing, and a range with at most one item is sorted.

Step. Let s≥2s \ge 2 and assume the claim for all shorter ranges. Line L2 gives lo<mid<hilo < mid < hi, so the calls of lines L3 and L4 are on ranges of lengths ⌊s/2⌋\lfloor s/2 \rfloor and ⌈s/2⌉\lceil s/2 \rceil, both less than ss. By the induction hypothesis, line L3 returns x=inv⁡(A[lo…mid−1])x = \operatorname{inv}(A[lo \ldots mid-1]), sorts that part and changes nothing else; in particular the right half is not changed. Line L4 then returns y=inv⁡(A[mid…hi−1])y = \operatorname{inv}(A[mid \ldots hi-1]) for the original right half and sorts it, without changing the left half. Both halves keep their multisets LL and MM. By the lemma, MERGE-AND-COUNT returns χ(L,M)\chi(L, M) and leaves the range sorted with multiset L∪ML \cup M. By (1), line L5 returns x+y+χ(L,M)=inv⁡(A[lo…hi−1])x + y + \chi(L, M) = \operatorname{inv}(A[lo \ldots hi-1]). Each call is on a strictly shorter range, so the recursion terminates. ■\blacksquare

Repeated keys. The proof never assumes distinct items. An equal pair B[i]=rjB[i] = r_j goes to line L9, and it is not counted, which matches the strict test A[p]>A[q]A[p] > A[q] in the definition of an inversion.

Back to Counting inversions by merge sort