“算法选择取决于被预处理的对象。KMP 预处理一个模式并在线读取任意文本;后缀树和 FM index预处理固定全文,以支持许多模式查询,后者还追求压缩空间。把全文索引称为“更快的 KMP”会混…”
形式陈述 ​
构造对象 ​
设原文本为
取一个不属于字母表的唯一终止符
后缀树是
所形成Trie的路径压缩版本:把所有内部度为 1 的非根路径压成一条边。终止符只需在原文本中从未出现,就能保证没有一个后缀是另一个后缀的前缀,因此每个后缀都对应独立叶。把终止符再约定为字典序最小,只是为了让后缀排序顺序更方便,并不是“后缀都成为叶”的必要条件。
每条边标签是
模式查询 ​
给定不含终止符的模式
字符比较总共消费
直觉
朴素后缀 Trie 同时存放
终止符把“某个后缀恰好在内部节点结束”的情况显式推到叶上。它不是为了参与普通模式匹配,而是给每条后缀一个独一无二的结尾,使后缀起点、叶和报告位置形成一一对应。
例子与边界
对 banana$ 采用 0 起点编号。后缀 1 是 anana$,后缀 3 是 ana$,二者共享前缀 ana,随后分别沿 n... 与 $ 分叉。压缩结构只保留这次真正分叉;ana 可以作为一条边标签引用 S[1..4),不需要在每条相关后缀路径中复制三个字符。
查询 ana 时,从根选择以 a 开头的边并消费三个字符。模式可能正好停在显式节点,也可能停在边中间;无论哪种情况,该 locus 下的叶 1 和 3 都被报告。若第二个字符已经失配,则立即返回空结果,不需要检查其他后缀。
终止符必须是新字符。若直接对不带终止符的 aaaa 建压缩 Trie,短后缀会在长后缀路径的内部结束,叶与后缀不再天然一一对应,算法和节点计数就必须额外维护 terminal 标记。允许这种“隐式后缀树”并非错误,但它是另一套表示约定,不能与显式终止符版本混写。
显式节点、隐式位置与 suffix link ​
根到显式节点的拼接标签称为该节点的 path label,其长度是字符串深度。压缩边中间的位置是 implicit locus,不需要分配节点,却仍可成为模式匹配的终点。
若某个非根内部节点的 path label 为
线性时间构建还依赖字母表模型。常数字母表、整数字母表或可在线性总成本内维护的子边字典可以达到
推论与应用
后缀树可在线性空间内支持子串存在性、出现位置报告、最长重复子串和多文本公共子串等任务。许多应用在树节点上再维护字符串深度、叶区间、最低公共祖先或文档颜色信息;这些是建立在拓扑索引之上的附加层,不应混入后缀树的基本定义。
Suffix array保存后缀的字典序排列,是后缀树叶序的线性化,通常更紧凑但查询依赖二分、LCP 或额外索引。Suffix automaton压缩的是子串的右端等价类,识别全部子串语言;它的状态不对应后缀树节点,二者不能仅因都能做子串查询而视为同一种结构。
参考资料
- Peter Weiner, “Linear Pattern Matching Algorithms,” 14th Annual Symposium on Switching and Automata Theory, 1973, pp. 1–11.
- Edward M. McCreight, “A Space-Economical Suffix Tree Construction Algorithm,” Journal of the ACM 23(2), 1976, pp. 262–272.
- Esko Ukkonen, “On-line Construction of Suffix Trees,” Algorithmica 14, 1995, pp. 249–260.
- Dan Gusfield, Algorithms on Strings, Trees, and Sequences, Cambridge University Press, 1997, Chapters 5–7.