Algorithm 构造后缀树的最坏情况时间复杂度是如何线性的?

Algorithm 构造后缀树的最坏情况时间复杂度是如何线性的?,algorithm,data-structures,big-o,time-complexity,suffix-tree,Algorithm,Data Structures,Big O,Time Complexity,Suffix Tree,我很难理解构造后缀树的最坏情况时间复杂度是线性的,特别是当我们需要为可能由重复的单个字符组成的字符串(如“aaaaa”)构建后缀树时 即使我要为“aaaaa”构造一个压缩后缀树,我也无法真正压缩任何节点,因为从节点开始的两条边都不能有以相同字符开头的字符串标签 这将产生一个高度为5的后缀树,在每次插入后缀时,我需要不断地从根遍历到叶 我是这样接近的: 后缀:a,aa,aaa,aaaa,aaaa 创建根节点,创建一个带有“a”的边,并将其连接到一个新节点,其左侧带有“$”,然后重复此过程,直到我们

我很难理解构造后缀树的最坏情况时间复杂度是线性的,特别是当我们需要为可能由重复的单个字符组成的字符串(如“aaaaa”)构建后缀树时

即使我要为“aaaaa”构造一个压缩后缀树,我也无法真正压缩任何节点,因为从节点开始的两条边都不能有以相同字符开头的字符串标签

这将产生一个高度为5的后缀树,在每次插入后缀时,我需要不断地从根遍历到叶

我是这样接近的: 后缀:a,aa,aaa,aaaa,aaaa

创建根节点,创建一个带有“a”的边,并将其连接到一个新节点,其左侧带有“$”,然后重复此过程,直到我们可以aaaaa

这将导致O(n^2)而不是O(n)。
我在这里遗漏了什么?

我同意这些评论,但这里有更多的细节:

您描述的形成
aaaaaaa
树的过程是O(n),而不是O(n^2)。节点和叶创建是固定时间操作,您可以执行n==5次。你对O(n^2)的假设似乎是基于这样一个想法,即你在每一步都要从根到叶遍历,但没有必要这样做;e、 g.在Ukkonen的算法中:

  • 在插入下一个节点之前,可以保留一个指向您离开的节点的指针
  • 在重复的情况下,直到重复结束,你才执行任何工作,然后你一个接一个地插入最后的
    $
    标记,沿着你创建的边缘上的字符,以及在更复杂的重复情况下的后缀链接链

Ukkonen算法(细节)为何为O(n)的关键在于它维护了一个插入位置的“内存”,形式为(a)指向上一次插入位置的指针,以及(b)后缀链接网络。这个网络可能很大,但每个内部节点只有一个后缀链接,所以它的大小仍然是O(n)。

你忽略了一个事实,即构造算法比你描述的要复杂得多。顺便说一句,压缩是由于使用字符串索引标记边,而不是使用真实的子字符串。您有n个叶节点,因此最多有n-1个内部节点,这将产生最多2n-1条边,每条边都标有O(1)个单词。这就是为什么我们可以首先将后缀树存储在O(n)空间中(但不确定这是否是您困惑的一部分)