Algorithm Search⌘K

Proofs: Library sort

These are the human proofs of Library sort, at full length.

Library sort returns the stable sorted order full

This proof shows: correctness, termination.

Each inserted item is a pair (x,p)(x, p) of an item and its input position. Write (y,i)≺(x,p)(y, i) \prec (x, p) when y<xy < x, or neither y<xy < x nor x<yx < y and i<pi < p. The positions are distinct, so ≺\prec is a strict total order on the pairs, and listing the pairs in ≺\prec order lists the items in the stable sorted order.

Call a slot array ordered if its filled slots, read from left to right, are increasing in ≺\prec.

Lemma 1 (spreading). In line L5, with kk items and L>kL > k slots, the slots ⌊(2j+1)L/(2k)⌋\lfloor (2j+1) L / (2k) \rfloor for j=0,…,k−1j = 0, \ldots, k-1 are distinct and lie in [0,L)[0, L), so spreading an ordered list gives an ordered array.

Proof. The values (2j+1)L/(2k)(2j+1) L / (2k) grow by L/k>1L/k > 1 from one jj to the next, and two reals that differ by more than 1 have different floors, so the floors are strictly increasing. The largest is ⌊(2k−1)L/(2k)⌋<L\lfloor (2k-1) L / (2k) \rfloor < L. □\square

Lemma 2 (the search). On an ordered array, line L9 ends with a slot bb such that every filled slot before bb holds a pair ≺(x,p)\prec (x, p) and every filled slot from bb on holds a pair ≻(x,p)\succ (x, p).

Proof. The pair (x,p)(x, p) is not yet in the array, so every placed pair is either ≺\prec or ≻\succ it. The search keeps lo≤hilo \le hi and the invariant: filled slots before lolo hold pairs ≺(x,p)\prec (x, p), and filled slots from hihi on hold pairs ≻(x,p)\succ (x, p). It holds for lo=0lo = 0, hi=Lhi = L. Take mid=⌊(lo+hi)/2⌋mid = \lfloor (lo + hi)/2 \rfloor, so lo≤mid<hilo \le mid < hi, and let jj be the first filled slot in [mid,hi)[mid, hi). If there is none, the slots [mid,hi)[mid, hi) are empty, and hi←midhi \leftarrow mid keeps the invariant. If (x,p)≺S[j](x, p) \prec S[j], then the filled slots from midmid on are S[j]S[j], which is ≻(x,p)\succ (x,p), and slots after jj; since the array is ordered, those are ≻S[j]\succ S[j] and so ≻(x,p)\succ (x, p); hi←midhi \leftarrow mid keeps the invariant. Otherwise S[j]≺(x,p)S[j] \prec (x, p), and so are all filled slots before jj, so lo←j+1lo \leftarrow j + 1 keeps it. In the first two cases hihi drops, and in the third lolo rises past mid≥lomid \ge lo, so hi−lohi - lo falls each step and the loop ends with lo=hi=blo = hi = b. □\square

Lemma 3 (insertion). If the array is ordered and has an empty slot, INSERT(S,x,p)(S, x, p) ends and leaves an ordered array whose pairs are the old ones plus (x,p)(x, p).

Proof. By Lemma 2 and line L10, qq and rr are consecutive filled slots with S[q]≺(x,p)≺S[r]S[q] \prec (x, p) \prec S[r], where q=−1q = -1 or r=Lr = L stands for no slot. All slots strictly between qq and rr are empty.

If r−q>1r - q > 1, line L11 writes into the empty slot ⌊(q+r)/2⌋\lfloor (q + r)/2 \rfloor, which lies strictly between them, and the array stays ordered.

Otherwise r=q+1r = q + 1. In line L12, ee is the first empty slot after rr, so S[r…e−1]S[r \ldots e-1] are filled. Shifting them one slot right fills slot ee and empties slot rr, keeping their order. Then (x,p)(x, p) goes into slot rr, between S[q]S[q] and the old S[r]S[r], now in slot r+1r + 1. In line L13 there is no empty slot after rr and none between qq and rr, so the empty slot that exists is before qq, and ee is the last one. The slots e+1,…,qe+1, \ldots, q are filled; shifting them one slot left empties slot qq and keeps their order, and (x,p)(x, p) goes into slot qq, after the old S[q]S[q], now in slot q−1q - 1, and before S[r]S[r]. Each case writes (x,p)(x, p) once and loses no pair. The scans for qq, rr and ee run over finite ranges, so INSERT ends. □\square

Theorem. LIBRARY-SORT ends and leaves AA in stable sorted order.

Proof. We show by induction on the rounds that at line L3 the placed items are the pairs (A[π(t)],π(t))(A[\pi(t)], \pi(t)) for t<kt < k, listed in ≺\prec order. This holds at line L2 with k=1k = 1. In a round, k<mk < m and L=⌊(1+ε)m⌋+1>m>kL = \lfloor (1 + \varepsilon) m \rfloor + 1 > m > k, so by Lemma 1 spreading gives an ordered array. Each insertion of the round starts with fewer than m<Lm < L items, so an empty slot exists, and Lemma 3 applies. After the round the array is ordered and holds the pairs for t<mt < m, and line L7 lists them in order. The rounds double kk until k=nk = n, so there are ⌈lg⁡n⌉\lceil \lg n \rceil rounds and the loop ends. Then the placed items are all nn pairs in ≺\prec order, and line L8 writes their items to AA in stable sorted order. ■\blacksquare

Back to Library sort