我需要(对于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进行组织,但是树的乘法仍然很慢,因为我必须自己复制每个树级而不是仅仅复制整个树
答案 0 :(得分:3)
当你添加R时,给它指向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)。 / p>
答案 1 :(得分:0)
也许看一下T9字典的Androids代码。 AFAIR它看起来很平坦,但基本上它们所做的是构建一个字母树,以便从上到下遍历树形成单词。我认为他们使用相对偏移从节点跳到下一个(如链接列表)。
所以你应该能够在一次运行中复制整个树。
我不记得你的确切布局,我认为它并没有像我在这里那样做丑陋的填充,但继续w /你的例子它看起来像这样的东西(!):
# your tree
__________
/// _ \ _
/// /// \ \ /// \
A007021B007000D000000C007014E000000F000000
\\\_/ \\\_____/
# copying it, "under" R:
__________ __________
_ /// _ \ _ /// _ \ _
/// \ /// /// \ \ /// \ /// /// \ \ /// \
R007049A007021B007000D000000C007014E000000F000000A007021B007000D000000C007014E000000F000000
\\\ \\\_/ \\\_____/ / \\\_/ \\\_____/
\\\______________________________________/