尝试和树之间的区别?

Posted

技术标签:

【中文标题】尝试和树之间的区别?【英文标题】:Difference between Tries and Trees? 【发布时间】:2011-06-11 21:28:38 【问题描述】:

我远程记得尝试不存储每个节点的全部数据,只存储父节点的后缀。

树确实存储了整个数据,但仅根据前缀进行自我组织。

因此尝试变得更小,例如可以很好地压缩字典。

这真的是唯一的区别吗?

从实际应用中,我记得尝试在范围查询中更快。甚至还有特殊的 solr/lucene trie 字段来加速范围查询。但这是怎么回事?

try 和 tree 的实际区别是什么,优缺点是什么?

【问题讨论】:

【参考方案1】:

树是递归节点的一般结构。树的种类很多。流行的是binary tree 和balanced tree。 Trie 是一种树,有许多名称,包括前缀树、数字搜索树和检索树(因此得名“trie”)。

每种树都有不同的用途、结构和行为。例如,二叉树存储可比较项(例如数字)的集合。因此,它可以用于存储一组数字,或索引可以用数字表示的其他数据(例如,可以散列的对象)。它的结构经过排序,因此可以快速搜索以找到单个项目。其他树结构,例如平衡树,原则上类似。

trie 表示其结构中的一个序列。它的不同之处在于它存储值序列而不是单个值。每个级别的递归都说“输入列表的第 I 项的值是什么”。这与将单个搜索值与每个节点进行比较的二叉树不同。

【讨论】:

trie 是不是有点蹩脚?除了存储空间之外,二叉树不是在所有方面都优于 trie 吗? 每个数据结构都有一个位置。如何查找所有具有相同前缀的字符串? O(n) 次访问? tree 不会也这样做吗?让我们有 10 亿个条目,找到 20 的前缀。Trie 分 20 步完成。树以 lg 1B / lg 2 = 30 步完成。现在使用相同的 1B 条目,我们发现前缀为 40。Tree 仍然需要 30 步,但 trie 需要 40 步。前缀为 100 时,trie 现在需要 100 步,而树仍然需要 30 步。 等等,对我来说,尝试似乎更好。由于在 trie 中的查找在字符串的长度中是 O(m),而在树中它们是 O(m * log n) 其中 n 是节点数,因为比较两个字符串需要最坏的情况 O(m) 时间,你需要做最坏的情况O(log n) 比较。而尝试进行O(1) 字符比较。 @Pacerier Trie 对基本上所有操作都有更好的渐近性,因为 Trie 中的比较是 O(1),因为您正在比较值的恒定大小子部分,而它们是 O(m) 在树。【参考方案2】:

二叉树bst通常用于存储数值。 bst 中插入、删除和搜索的时间复杂度为 O(log(n))。二叉树的每个节点最多有2个子节点。

Trie : trie 的每个节点都由多个分支组成。每个分支代表一个可能的键字符。我们需要将每个键的最后一个节点标记为叶子节点。将使用一个trie节点字段值来区分节点是否为叶子节点(value字段还有其他用途)

要了解尝试,请参阅此 topcoder 教程。 https://www.topcoder.com/community/data-science/data-science-tutorials/using-tries/

【讨论】:

【参考方案3】:

刚刚从this talk 那里得到了一些见解,即使 linux 内核中使用的基数树与***上的略有不同。

树只存储键,它们不存储与 键。

【讨论】:

【参考方案4】:

尝试的优点:

搜索时间只取决于搜索字符串的长度。

搜索未命中只涉及检查几个字符(特别是搜索字符串和存储在树中的语料库之间的最长公共前缀)。

trie 中的唯一键没有冲突。

无需提供散列函数或将散列函数更改为 更多的键被添加到一个 trie。

trie 可以通过键提供条目的字母顺序。

不幸的是,没有完美的数据结构。所以即使尝试也有一些缺点:

当容器太大而无法放入内存时,在查找数据时尝试可能比哈希表慢。哈希表需要更少的磁盘访问,甚至只需要一次访问,而对于长度为 m 的字符串,trie 需要 O(m) 次磁盘读取。

哈希表通常分配在一个大的连续内存块中,而 trie 节点可以跨越整个堆。所以,前者会更好 利用局部性原则。

trie 的理想用例是存储文本字符串。理论上,我们可以将任何值(从数字到对象)字符串化并存储。然而,如果我们要存储浮点数,例如,由于一些问题,有些边缘情况可能会产生长的无意义路径,例如周期数或超越数,或某些浮点运算的结果,例如 0.1+0.2具有双精度表示。

尝试对节点和引用有内存开销。

当您必须经常执行前缀搜索时使用尝试(longestPrefix 或 keysWithPrefix)。存储数据时使用哈希表 在慢速支持(如磁盘)或内存位置很重要时。

【讨论】:

以上是关于尝试和树之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

网站结构分为哪几种的?扁平型结构和树型结构,他们的含义是啥?有啥区别和作用呢?

fetch 和 $.getjson 之间的区别

"和'之间的区别[重复]

VBA中两个二维数组之间的区别

isAuthenticated 和 isFullyAuthenticated 之间的区别

业力记者之间有啥区别?