Algorithm Search⌘K

Proofs: Strand sort

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

Strand sort returns the items in sorted order, and it is stable full

This proof shows: correctness.

We write AjA_j for the list AA at the start of round jj of the loop of line L2, SjS_j for the strand of round jj, and RjR_j for RR after round jj, with R0R_0 empty and A1A_1 the input.

Lemma 1 (one round). SjS_j is non-decreasing. Each item of AjA_j goes to exactly one of SjS_j and UU, and each of the two lists keeps the order of AjA_j.

Proof. Line L3 puts Aj[0]A_j[0] in SjS_j. The loop of line L4 visits each other item once, in order, and appends it to the end of UU (line L5) or of SjS_j (line L6). An item goes to SjS_j only when it is not less than the last item of SjS_j, so SjS_j stays non-decreasing. □\square

Lemma 2 (MERGE). For two sorted lists XX and YY, MERGE(X,Y)(X, Y) returns a sorted list of the items of XX and YY. It keeps the order of the items of XX, and of the items of YY, and on a tie it puts the item of XX first.

This is the merge of the merging-sorted-lists page, with the rule to take the front item of XX unless the front item of YY is smaller.

Theorem 1. STRAND-SORT(A)(A) stops and returns the items of AA in sorted order.

Proof. Invariant: before round jj, Rj−1R_{j-1} is sorted, and Rj−1R_{j-1} and AjA_j together hold the items of the input. It holds for j=1j = 1. If it holds before round jj, then by Lemma 1, SjS_j is sorted and SjS_j and Aj+1=UA_{j+1} = U together hold the items of AjA_j; by Lemma 2, RjR_j is sorted and holds the items of Rj−1R_{j-1} and SjS_j. So the invariant holds before round j+1j + 1. Each round moves Aj[0]A_j[0] into SjS_j, so ∣Aj+1∣<∣Aj∣|A_{j+1}| < |A_j|, and the loop stops after at most nn rounds, with AA empty. Then RR is sorted and holds all the items. ■\blacksquare

Theorem 2 (stability). If yy and zz have equal keys and yy comes before zz in the input, then yy comes before zz in the output.

Proof. Let yy be in strand SaS_a and zz in strand SbS_b.

First, a≤ba \le b. Suppose b<ab < a. In round bb, both yy and zz are in AbA_b, and by Lemma 1 the earlier rounds kept the input order, so yy comes before zz in AbA_b. So yy is not Ab[0]A_b[0], because Ab[0]A_b[0] goes to SbS_b. The scan visits yy before zz and sends yy to UU, so at that moment y<last(Sb)y < \text{last}(S_b). The last item of SbS_b never decreases during the scan, and zz has the key of yy, so when zz is visited, z<last(Sb)z < \text{last}(S_b) and zz goes to UU too. This contradicts z∈Sbz \in S_b.

If a=ba = b, then yy is before zz in SaS_a by Lemma 1, and the merges keep the order of the items of each input list (Lemma 2), so yy stays before zz.

If a<ba < b, then yy is in Rb−1R_{b-1} when SbS_b is merged. By Lemma 2, on equal keys the item of Rb−1R_{b-1} comes first, and any item between them in Rb−1R_{b-1} is also kept in order. So yy comes before zz in RbR_b, and the later merges keep the order of the items of RR. ■\blacksquare

The number of strands. Let kk be the number of rounds. Two items of a strictly decreasing subsequence of the input cannot be in the same strand: they keep their order in AjA_j, and a strand is non-decreasing. So kk is at least the length of each strictly decreasing subsequence. Conversely, for j>1j > 1 each item xx of SjS_j was in Aj−1A_{j-1} and went to UU, so it was visited after an item ww of Sj−1S_{j-1} with x<wx < w, and ww comes before xx in the input. Starting from an item of SkS_k and following these items back to S1S_1 gives kk items, each earlier in the input and larger than the next. So the longest strictly decreasing subsequence has length exactly kk.

Back to Strand sort