我第一次使用trie。我想知道哪个是用于trie的最佳数据结构,同时决定哪个是应该遍历的下一个分支。我正在寻找一个数组,一个hashmap和一个链表。
答案 0 :(得分:12)
这些选项中的每一个都有其优点和缺点。
如果将子节点存储在数组中,那么只需索引到数组中就可以非常有效地查找要访问的子节点。但是,每个节点的空间使用率会很高:O(|Σ|),其中Σ是您的单词可以形成的字母集,即使这些孩子中的大多数都是空的。
如果将子节点存储在链表中,那么查找子节点所需的时间将为O(|Σ|),因为您可能需要扫描链表的所有节点以查找子节点你要。另一方面,空间效率会非常好,因为您只存储您正在使用的孩子。你也可以考虑在这里使用一个固定大小的数组,它具有更好的空间使用率,但会导致非常昂贵的插入和删除。
如果将子节点存储在哈希表中,那么查找子节点的(预期)时间将为O(1),并且内存使用量将仅与您拥有的子节点数成比例(大致)。有趣的是,因为您事先知道要进行散列的值是什么,所以可以考虑使用dynamic perfect hash table来确保最坏情况下的O(1)查找,但会牺牲一些预计算。
另一种选择是将子节点存储在二叉搜索树中。这产生了ternary search tree数据结构。此选择介于链接列表和散列表选项之间 - 空间使用率较低,您可以有效地执行前置和后续查询,但由于BST中的搜索成本,执行查找的成本略有增加。如果您有一个永远不会发生插入的静态线索,您可以考虑在每个点使用weight-balanced trees作为BST;这为搜索提供了出色的运行时间(O(n + log k),其中n是要搜索的字符串的长度,k是trie中的单词总数)。
简而言之,数组查找速度最快,但在最坏的情况下,它的空间使用率最差。一个静态大小的数组具有最佳的内存使用率,但昂贵的插入和删除。哈希表具有相当快的查找速度和良好的内存使用率(平均而言)。二进制搜索树位于中间的某个位置。我建议在这里使用哈希表,但是如果你对空间进行溢价并且不关心查找时间,那么链表可能会更好。另外,如果你的字母表很小(比如你正在制作二进制文件),那么数组开销也不会太差,你可能想要使用它。
希望这有帮助!
答案 1 :(得分:0)
如果您正在尝试为字母表构建trie,我建议使用数组然后使用particia树(空间优化的trie)。 http://en.wikipedia.org/wiki/Radix_tree
这将允许您使用数组进行快速查找,并且如果某个节点的分支因子较低,则不会浪费太多空间。