【问题标题】:Merging 2 DIFFERENT AVL trees合并 2 个不同的 AVL 树
【发布时间】:2011-05-26 09:38:22
【问题描述】:

假设我有两棵 AVL 树并且我知道它们各自的大小。但是,我不知道是否有重复的节点,或任何其他信息。将它们合并到新的 AVL 树中的最有效方法是什么?原来的树可以被破坏。

【问题讨论】:

  • 这不完全是重复的。链接中的条件受到更多限制:“第一棵树中的每个元素都小于第二棵树中的任何元素”
  • @bronzebeard:问题不同。你所指的有一个条件大大简化了问题,它的解决方案在这里不适用。

标签: c++ c algorithm data-structures avl-tree


【解决方案1】:
  1. 将您的树 T1T2 转换为排序列表 L1L2
  2. L1L2 合并到一个排序列表L
  3. 再次将L 转换为树T

IIRC 所有这些操作都是 O(N),所以完全合并也是 O(N)。

如果您的 AVL 树表示允许有效地迭代它们(例如,使用反向指针、延续、惰性求值等),那么您应该也可以在没有中间列表的情况下完成它。

更新:由于您的编程语言似乎是 C/C++,您可能会暂时滥用您的 AVL 节点结构作为链表中的节点,然后再将它们再次用于输出树。

更新 2:@hwlau:这是 O(N),我使用我自己在 Prolog 中的 AVL 实现检查了它,可从 avl.pl 和这个测试程序 avl_test.pl 检查数字合并大小为 1、2、4、8、16、...的 AVL 树时的操作次数。

这是输出:

timing avl_merge, size: 128
% 1,790 inferences, 0.000 CPU in 0.001 seconds (0% CPU, Infinite Lips)
timing avl_merge, size: 256
% 3,591 inferences, 0.010 CPU in 0.002 seconds (430% CPU, 359100 Lips)
timing avl_merge, size: 512
% 7,176 inferences, 0.030 CPU in 0.028 seconds (107% CPU, 239200 Lips)
...
timing avl_merge, size: 32000
% 451,839 inferences, 0.490 CPU in 0.499 seconds (98% CPU, 922120 Lips)
timing avl_merge, size: 64000
% 903,682 inferences, 0.900 CPU in 0.964 seconds (93% CPU, 1004091 Lips)
timing avl_merge, size: 128000
% 1,807,363 inferences, 2.420 CPU in 2.559 seconds (95% CPU, 746844 Lips)

很明显,推理/操作的数量与合并树的大小成正比,因此算法的复杂度为 O(N)。

【讨论】:

  • 我想知道如何在 O(N) 时间内将列表转换为树 :)
  • @hwlau:我几乎可以肯定你可以在 O(N) 时间内将 排序 列表转换为树。
  • @salva:我认为你不能在 O(N) 中转换列表,但你可以转换向量。
  • @Juraj Blaho:如果您可以在 O(N) 中将向量转换为 AVL,您也可以在 O(N) 中将列表转换为 AVL,因为将列表转换为向量也是O(N) 次操作!
  • @salva: Sor,所以算法是以中间元素为根,对左右排序的元素进行递归操作,所以是O(N)。我不确定反向指针的实现是否允许您在线性时间内构建。还有一条评论,你最后三个数据似乎是 runtime > N.
【解决方案2】:

它不是最有效的,但绝对是最容易实现的。您可以将第二棵树中的所有节点添加到第一棵树。您不需要从第二棵树中删除节点。然后,您只需破坏第二棵树并因此获得第一棵树。时间复杂度为O(N*log(N))

【讨论】:

  • 严格来说,这个方法的复杂度是O(M*log(N+M))。当其中一棵树比另一棵树小得多时,此方法可能是合适的。
  • 事实上,这种方法在某些情况下比@salva 建议的执行速度更快,假设您有具有 1000 个节点的树 A 和具有 3 个节点的树 B。您的方法只需要 3 次迭代,而 salva 的方法至少需要 (1000+3) 次迭代。
  • @YuriYaryshev,这正是我之前的评论所说的,对吧?
猜你喜欢
  • 1970-01-01
  • 2021-11-14
  • 2011-01-03
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多