Algorithm 如何在哈希表和Trie(前缀树)之间进行选择?
因此,如果我必须在哈希表或前缀树之间进行选择,有哪些区别因素会导致我选择其中一个而不是另一个。从我自己天真的观点来看,使用trie似乎有一些额外的开销,因为它不是以数组的形式存储的,但就运行时间而言(假设最长的键是最长的英语单词),它基本上可以是O(1)(相对于上限)。也许最长的英语单词是50个字符 一旦得到索引,哈希表就可以立即查找。对键进行散列以获得索引,但似乎需要将近50个步骤Algorithm 如何在哈希表和Trie(前缀树)之间进行选择?,algorithm,data-structures,hashtable,trie,Algorithm,Data Structures,Hashtable,Trie,因此,如果我必须在哈希表或前缀树之间进行选择,有哪些区别因素会导致我选择其中一个而不是另一个。从我自己天真的观点来看,使用trie似乎有一些额外的开销,因为它不是以数组的形式存储的,但就运行时间而言(假设最长的键是最长的英语单词),它基本上可以是O(1)(相对于上限)。也许最长的英语单词是50个字符 一旦得到索引,哈希表就可以立即查找。对键进行散列以获得索引,但似乎需要将近50个步骤 有人能给我提供一个更有经验的观点吗?谢谢 这完全取决于你想解决什么问题。如果您需要做的只是插入和查找,请使用哈希
有人能给我提供一个更有经验的观点吗?谢谢 这完全取决于你想解决什么问题。如果您需要做的只是插入和查找,请使用哈希表。如果您需要解决更复杂的问题,例如前缀相关的查询,那么trie可能是更好的解决方案。一些(通常是嵌入式实时)应用程序要求处理时间独立于数据。在这种情况下,哈希表可以保证已知的执行时间,而trie根据数据而变化。尝试的优点: 基本要素:
- 可预测的O(k)查找时间,其中k是键的大小
- 如果不存在查找,则查找可能需要不到k个时间
- 支持有序遍历
- 不需要哈希函数
- 删除很简单
- 您可以快速查找键的前缀,枚举具有给定前缀的所有条目,等等
- 如果有许多通用前缀,则共享它们所需的空间
- 不可变尝试可以共享结构。您可以构建一个只沿一个分支不同的新trie,而不是就地更新trie,其他地方指向旧trie。这对于并发、表的多个同时版本等非常有用
- 不变的trie是可压缩的。也就是说,它还可以通过hash考虑在后缀上共享结构
- 每个人都知道哈希表,对吗?您的系统已经有了一个很好的优化实现,比大多数情况下的尝试都要快
- 你的钥匙不需要有任何特殊的结构李>
- 比明显的链接trie结构更节省空间(请参见下面的评论)
每个人都知道哈希表及其用途,但它并不是一个固定的查找时间,它取决于哈希表有多大,以及哈希函数的计算复杂度 在大多数工业场景中,即使是很小的延迟/可伸缩性也很重要(例如:高频交易),创建用于高效查找的大型哈希表并不是一个优雅的解决方案。为了减少缓存丢失,还必须考虑数据结构在内存中所占空间的优化
trie更好地满足需求的一个很好的例子是消息传递中间件。您有一百万个不同类别的消息订阅者和发布者(用JMS术语-主题或交换),在这种情况下,如果您想根据主题(实际上是字符串)过滤消息,您肯定不想为一百万个主题的订阅创建哈希表。更好的方法是将主题存储在trie中,因此当根据主题匹配进行过滤时,其复杂性与主题/订阅/发布者的数量无关(仅取决于字符串的长度)。我喜欢它,因为您可以创造性地使用此数据结构来优化空间需求,从而降低缓存未命中率 有一件事我没有看到有人明确提到,我认为要记住这件事很重要。哈希表和各种类型的try通常都有
O(k)
操作,其中k
是字符串的长度,单位为位(或等效为字符)
这是假设你有一个好的散列函数。如果您不希望“farm”和“farm animals”散列为相同的值,那么散列函数将必须使用密钥的所有位,因此散列“farm animals”的时间应该是“farm”的两倍(除非您处于某种滚动散列场景中,但也有一些类似的操作节省场景)。用香草果酱,很清楚为什么插入“农场动物”的时间是“农场”的两倍。从长远来看,压缩尝试也是如此。哈希表实现与基本的Trie实现相比,空间效率更高。但是对于字符串,排序在大多数实际应用中是必要的。但是哈希表完全扰乱了字母顺序。现在,如果您的应用程序正在执行基于词法顺序的操作(如部分搜索、具有给定前缀的所有字符串、按排序顺序排列的所有单词),则应该使用Tries。仅对于查找,应使用哈希表(可以说,它提供了最短的查找时间)
p.S.:除此之外,三元搜索树(TST)将是一个很好的选择。它的查找时间比哈希表长,但在所有其他操作中都是高效的。而且,它比tries更节省空间。在trie上的插入和查找与输入字符串O(s)的长度成线性关系 散列将为查找ans插入提供一个O(1),但首先必须根据输入字符串计算散列,该字符串也是O(s) 结论:在这两种情况下,渐近时间复杂度都是线性的 trie的开销比