Algorithm Search⌘K

Proofs: Larsson-Sadakane algorithm

These are the human proofs of Larsson-Sadakane algorithm, at full length.

Larsson-Sadakane suffix sorting is correct and ends after O(log n) passes full

This proof shows: correctness, termination.

Notation. T=T[0…n−1]T = T[0 \ldots n-1] with n≥1n \ge 1, 0-based, no sentinel, and Ti=T[i…n−1]T_i = T[i \ldots n-1]. The order of strings is lexicographic, with a proper prefix before the longer string. The algorithm keeps a permutation II of the positions (the array sa), and a partition of the ranks 0,…,n−10, \ldots, n-1 into consecutive blocks, the groups. For a position xx, V[x]V[x] is the last rank of the group that holds xx. A group of size 1 is sorted.

Invariant. At the start of each pass with the value hh:

(A) For ranks r<r′r < r' in different groups, TI[r]<TI[r′]T_{I[r]} < T_{I[r']}.

(B) The positions of one group all have the same prefix of length hh; in particular each of their suffixes has length at least hh.

(C) V[I[r]]V[I[r]] is the last rank of the group of rr.

From (A) and (C), V[x]<V[y]V[x] < V[y] implies Tx<TyT_x < T_y. From (B) and (C), V[x]=V[y]V[x] = V[y] implies that TxT_x and TyT_y share a prefix of length hh.

Lemma 1 (keys). At any moment during a pass with the value hh, (A) and (C) hold, and each group shares a prefix of length at least hh.

Proof. A split replaces a group by subgroups in consecutive ranks and gives each subgroup the number of its last rank, so (C) holds after each split. We show below that the subgroups are ordered by their suffixes, so (A) holds after each split. A subgroup is a subset of a group, so its members still share a prefix of length hh. □\square

Lemma 2 (one split). Let G=I[s…e−1]G = I[s \ldots e-1] be a group that is split during the pass with the value hh. For x∈Gx \in G, let key(x)=V[x+h]key(x) = V[x + h] if x+h<nx + h < n and −1-1 otherwise, read at the moment the split of GG starts. Then for x,y∈Gx, y \in G: if key(x)<key(y)key(x) < key(y), then Tx<TyT_x < T_y; and if key(x)=key(y)key(x) = key(y), then TxT_x and TyT_y share a prefix of length 2h2h.

Proof. By Lemma 1, xx and yy share a prefix uu of length hh, so Tx=u Tx+hT_x = u\,T_{x+h} and Ty=u Ty+hT_y = u\,T_{y+h}, and Tx<TyT_x < T_y if and only if Tx+h<Ty+hT_{x+h} < T_{y+h}, where TnT_n is the empty string. If key(x)=−1key(x) = -1, then Tx+hT_{x+h} is empty and Tx=uT_x = u is a proper prefix of TyT_y, unless y=xy = x; only one member of GG can have x+h=nx + h = n, because the suffix lengths differ. So key(x)<key(y)key(x) < key(y) with key(x)=−1key(x) = -1 gives Tx<TyT_x < T_y. If both keys are at least 0, then by Lemma 1 at the moment of reading, V[x+h]<V[y+h]V[x + h] < V[y + h] implies Tx+h<Ty+hT_{x+h} < T_{y+h}, and V[x+h]=V[y+h]V[x + h] = V[y + h] implies that Tx+hT_{x+h} and Ty+hT_{y+h} share a prefix of length hh, so TxT_x and TyT_y share a prefix of length 2h2h. □\square

The ternary-split quicksort sorts GG by keykey and makes each block of equal keys a subgroup. By Lemma 2 the subgroups are in the order of their suffixes, so (A) holds after the split, and each subgroup shares a prefix of length 2h2h.

Theorem 1 (pass). If (A), (B) and (C) hold at the start of a pass with the value hh, they hold at the start of the next pass with the value 2h2h.

Proof. The pass walks over all ranks. The sorted runs are skipped; they consist of groups of size 1, for which (B) holds for every length. Every group that is not sorted is split once, and by Lemma 2 each of its subgroups shares a prefix of length 2h2h. Lemma 1 gives (A) and (C). So (B) holds for 2h2h. □\square

Initialization. Line L2 sorts the positions by their first symbol and makes each block of equal symbols a group numbered by its last rank. (A) holds for different first symbols, (B) holds for h=1h = 1, and (C) holds by construction.

Theorem 2 (result and termination). The algorithm ends after at most ⌈log⁡2n⌉+1\lceil \log_2 n \rceil + 1 passes, and then II is the suffix array and VV is its inverse.

Proof. By (B), after the passes with h=1,2,…,2kh = 1, 2, \ldots, 2^k, each group shares a prefix of length 2k+12^{k+1}. Two different suffixes cannot share a prefix of length nn, since only T0T_0 has length nn. So once 2k+1≥n2^{k+1} \ge n, all groups have size 1, and the next pass finds no unsorted group and returns (line L9). When all groups have size 1, (A) says that II lists the suffixes in increasing order, and (C) says that V[I[r]]=rV[I[r]] = r. ■\blacksquare

Back to Larsson-Sadakane algorithm