Algorithm 基树中边缘标记/分割的具体实现细节

Algorithm 基树中边缘标记/分割的具体实现细节,algorithm,data-structures,radix-tree,Algorithm,Data Structures,Radix Tree,这是一个关于实践中通常做什么的问题 我们有一个有一个条目的基数树(不管出于什么原因,认为这是一个用于显示的条目): 然后我们想加入第二个条目 "team" 我们希望最终得到一个来自根的边 "te" 还有两条边,一条有 "sts are really hard, no one likes taking tests, they're the worst" 还有一个 "am" 天真地说,我们可以为“te”和“sts真的是…”创建新字符串(字符数组,无论什么)。这需要很多操作,即使我们的新词“团

这是一个关于实践中通常做什么的问题

我们有一个有一个条目的基数树(不管出于什么原因,认为这是一个用于显示的条目):

然后我们想加入第二个条目

"team"
我们希望最终得到一个来自根的边

"te"
还有两条边,一条有

"sts are really hard, no one likes taking tests, they're the worst"
还有一个

"am"
天真地说,我们可以为“te”和“sts真的是…”创建新字符串(字符数组,无论什么)。这需要很多操作,即使我们的新词“团队”很短

或者,我们可以使用“te”和“sts真的是…”标签,标签可以包含对相同原始字符串的引用,以及开始/结束值,即:

[0, 2] for "te"

[2],用于“sts真的是…”
这样我们就避免了任何复制,“team”的插入时间只取决于“team”的长度,而不取决于其他字符串的长度,在这种情况下,即“tests are really…”

因此,问题在于
O(k)
中的
k
是指插入的字符串的长度,还是迄今为止最长的字符串

显然,后一种实现更难,并且在实践中可能会使用更多内存(因为端点的存储),但理论上最坏情况下的时间似乎有所改善

我想知道是否有人知道在实践中通常会做什么

谢谢


编辑:我想后一种实现的一个问题是删除。如果您稍后插入“心灵感应”,但删除了“测试确实很难…”,“te”边将保留,并且对字符串的引用仍然比需要的长得多。

删除密钥的算法是找到其叶节点,删除它,如果该节点的父节点正好有一个子节点,则将两个子节点拼接


假设边标签以索引对的形式存储到整个键中,则可以通过调整剩余子项的较低索引来完成拼接。要“垃圾收集”已删除密钥的所有其他实例,可以向根方向扫描,重写涉及已删除密钥的边缘标签以引用同级。在最坏的情况下,我们必须一直扫描到根,渐近运行时间没有增加,但对于随机操作,预期的重写次数是恒定的。不清楚这种开销是否值得保存副本。

因此,通过重写涉及已删除密钥的边缘标签来引用兄弟姐妹,您的意思是让“te”实际指向“团队”或“心灵感应”?事实上,我在想我们永远不会储存所有的心灵感应。最初只存储插入时所需的内容,即“st”和“lepathy”,因为这样就不需要三个“te”——只有一个。如果我们将键存储在链表中而不是字符数组(更多内存),那么似乎不需要重写。不是对整个字符数组和端点的引用,而是对第一个listnode的引用。
[0, 2] for "te"
[2, <whatever it is>] for "sts are really..."