Proofs: Suffix tree from suffix array
These are the human proofs of Suffix tree from suffix array, at full length.
The stack scan builds the suffix tree from the suffix array and the LCP array full
This proof shows: correctness, complexity.
We use the pseudocode and notation of the page. The text has length and ends with a unique end marker, so no suffix is a prefix of another. Write for the suffix , so , and for the length of the longest common prefix.
Fact 1. For , . This is the standard property of sorted strings: the common prefix of and is a prefix of every string between them, and conversely the minimum over adjacent pairs is common to all of them.
Let be the compacted trie of : the tree whose nodes are the root, one leaf for each of these suffixes, and one internal node for each string that is the longest common prefix of two of them and is followed in them by two different symbols, with the children of each node in increasing order of their next symbol. (Here every leaf is a suffix, since none is a prefix of another.) is the suffix tree of .
Invariant. Before iteration (for ), the tree built is , each node has the right depth, a correct start and its children in order, and the stack holds, from bottom to top, the nodes of the path from the root to the leaf of . For the tree is the root alone and the stack is .
Iteration . Let (for , , and the leaf of becomes the only child of the root, which gives with the stack ). For , differs from as follows. Let be the point at depth on the path from the root to the leaf of ; it exists because . By Fact 1, the prefix of length of is the string at , and no earlier suffix shares more than symbols with . So in , leaves the old tree at : if is a node, the leaf of becomes a new child of it; if lies inside an edge, the edge is split by a new internal node at , whose children are the lower part of the edge and the new leaf. In both cases the next symbol of after is larger than that of , since , and larger than the next symbol of every earlier suffix through , since these suffixes are at most and share the string at ; so the new leaf is the last child of the node at .
Line L3 pops exactly the nodes of the path with depth greater than . If the new top has depth , it is the node at , and line L5 appends the leaf as its last child. Otherwise lies on the edge from the top, of depth below , to , the first popped node below it on the path, which is the last child of the top since the path is the rightmost one. Line L4 creates the node at with depth , puts it in place of , and makes its only child for now; its start is that of , which is a suffix below , so the labels of the two new edges are the two parts of the old label. Then line L5 appends the leaf. The depth of the leaf is , and its start is . The children stay in order, and the stack now holds the path from the root to the new leaf: the nodes below that were not popped, the node at , and the leaf. So the invariant holds for .
After the last iteration, the tree is , the suffix tree of . Every internal node other than the root has at least two children: it was created at line L4 with as a child, and the leaf of line L5 was appended right away.
Time. Each iteration pushes at most two nodes (lines L4 and L5), so at most pushes happen in total, and each iteration of the loop in line L3 pops one of them. All other work is constant per iteration. So the scan takes time, and it creates leaves and at most internal nodes.