有效地复制/乘法树
Posted
技术标签:
【中文标题】有效地复制/乘法树【英文标题】:Duplicate / multiplicate tree efficiently 【发布时间】:2013-04-17 07:08:10 【问题描述】:我需要(对于 g++)一个(计算时间)优化的算法树结构来复制/相乘一棵树。
我的树将是一个 k-ary 树,但不一定是填充的。 主要操作是将现有树相乘(最多 k 次)并将树作为子树添加到新节点。然后叶节点级别将被擦除以保持固定级别规则。
有人知道提供此功能的数据结构吗?
乘法示例:假设我们有一棵二叉树
A
|
/ \
/ \
B C
| / \
| / \
D E F
我们想添加一个新节点/相乘
R
/ \
/ \
.. ..
所以结果会是这样的
R
/ \
/ \
/ \
/ \
/ \
A A
| |
/ \ / \
/ \ / \
B C B C
| / \ | / \
| / \ | / \
D E F D E F
我试图在 std::vector 上以类似堆的结构组织它,但是乘以树仍然有点慢,因为我必须自己复制每个树级别,而不是一次复制整个树.
【问题讨论】:
@YochaiTimmerstd::map
可能是一棵树。但即使特定实现使用树,它也不允许直接操作该树。
【参考方案1】:
当你添加 R 时,给它 2 个指向 A 的指针是微不足道的,而不是从 A 开始复制整个子树。
R
/ \
| |
\ /
A
|
/ \
/ \
B C
| / \
| / \
D E F
这既快速又易于编码。
现在,如果您稍后想要更新树的一侧,而不是另一侧,那么问题就来了。例如,也许您想将“正确”的 F 更改为 G。此时您可以仅在某些节点上使用 copy-on-write 策略,在这种情况下会导致
R
/ \
/ \
A A <-- copied, left side points to B
| / \
/ \ * \
/ \ \
B C C <-- copied, left side points to E
| / \ / \
| / \ * \
D E F G
基本上,您只需将路径从更改点 (F/G) 复制到根(最容易实现)或直到共享的最高节点(本例中为 A)。
【讨论】:
【参考方案2】:也许可以看看 T9 词典的 android 代码。 AFAIR 它看起来很平坦,但基本上他们所做的是构建一个字母树,这样从上到下遍历树就可以生成单词。而且我认为他们使用相对偏移量从一个节点跳转到下一个节点(如链表)。
所以你应该能够一次复制整个树。
我不记得你的确切布局,我认为它没有像我在这里那样做丑陋的填充,但是继续你的例子,它看起来像这样(!):
# your tree
__________
/// _ \ _
/// /// \ \ /// \
A007021B007000D000000C007014E000000F000000
\\\_/ \\\_____/
# copying it, "under" R:
__________ __________
_ /// _ \ _ /// _ \ _
/// \ /// /// \ \ /// \ /// /// \ \ /// \
R007049A007021B007000D000000C007014E000000F000000A007021B007000D000000C007014E000000F000000
\\\ \\\_/ \\\_____/ / \\\_/ \\\_____/
\\\______________________________________/
【讨论】:
以上是关于有效地复制/乘法树的主要内容,如果未能解决你的问题,请参考以下文章