我读的越多,我就会因为某些原因而感到困惑
让我困惑的是以下内容:
我已经阅读了两种类型的实现。
Collection
个节点以及最后一个节点
每个节点使用一个布尔来确定我们是否到达了一个单词
走这条路在第一种情况下,没有提到它,但似乎我们必须保留所有字典单词(因为我们间接引用它们)。所以我们有array_size*numberOfNodes*lengthOfword + size of dictionary processed
在后一种情况下,我们不需要字典,因为字符直接存储在树中。所以在我看来,第二个实现更节省空间。但我不确定多少 我对实现的理解是否正确,是否有特定的理由选择其中一个?另外我们如何计算第二种情况的空间要求?
答案 0 :(得分:3)
尝试不会将原始单词存储在任何位置,而是隐式存储它们。 trie的基本结构如下:trie store中的每个节点
要确定一个单词是否在trie中,您从根目录开始,然后一次一个地遵循appropritately标记的指针。如果您到达标记为单词的节点,则该单词存在于trie中。如果您到达未标记的节点或从trie上掉下来,则该单词不存在。
上面列出的两种结构之间的区别在于如何存储子指针。在第一个版本中,子指针存储为字母表中每个符号一个指针的数组,这使得后续子指针非常快,但可能非常节省空间。在第二个版本中,您显式存储某种类型的集合,只包含您需要的标记指针。这个速度较慢,但是稀疏尝试的空间效率更高。
trie的空间使用取决于节点的数量(称为n),字母表的大小(称为k)以及表示子指针的方式。如果存储固定大小的指针数组,则空间使用量约为kn指针(n个节点,每个指针有k个指针),加上每个节点处标记的n位。例如,如果你有一个以排序顺序存储的动态指针数组,那么开销将是n个子指针总数加n位,加上存储单个集合所需空间量的n倍。
第一种方法的优点是速度和简单性,在密集尝试上具有非常好的性能。第二种是较慢但内存效率较高的稀疏尝试。
这些不是唯一可能的空间优化。 Patricia尝试只用一个孩子压缩节点,并且非常节省空间。 DAWG尝试将尽可能多的节点合并在一起,但不支持高效插入。
希望这有帮助!