有效地复制/复制树

时间:2013-04-17 07:08:11

标签: c++ performance algorithm data-structures tree-structure

我需要(对于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进行组织,但是树的乘法仍然很慢,因为我必须自己复制每个树级而不是仅仅复制整个树

2 个答案:

答案 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
     \\\ \\\_/                   \\\_____/      /  \\\_/                   \\\_____/
      \\\______________________________________/