两个AVL树的交集和并集的算法是什么?

时间:2012-11-21 09:15:33

标签: algorithm data-structures language-agnostic intersection avl-tree

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

您可以在线性时间内交叉任意两个排序列表。

  • 获取两个AVL树的有序(左子,然后父数据,然后右子)迭代器。
  • 偷看两个迭代器的头部。
    • 如果一个迭代器耗尽,则返回结果集。
    • 如果两个元素相等或正在计算联合,则将它们的最小值添加到结果集中。
    • 弹出最低(如果迭代器按升序排列)元素。如果两者相等,则弹出

这在O(n1 + n2)中运行,对于并集操作(您受输出大小限制)是最佳的。

或者,您可以查看较小树的所有元素,以查看它们是否存在于较大的树中。这在O(n1 log n2)中运行。


这是Google在其BigTable引擎中使用(或考虑使用)查找交叉点的算法:

  • 获取所有来源的迭代器
  • 以pivot = null
  • 开头
  • 按顺序遍历所有n个迭代器,直到它们中的任何一个耗尽。
    • 在此迭代器中找到大于枢轴的最小元素。
    • 如果元素是枢轴
      • 增加pivot在
      • 中的迭代器数
      • 如果此pivot位于所有迭代器中,请将pivot添加到结果集。
    • 否则
      • 重置数据透视表所在的迭代器数
      • 使用找到的元素作为新的支点。

在二叉树迭代器中查找元素或下一个最大元素:

  • 从当前元素开始
  • 向上走,直到当前元素大于要搜索的元素或您在根
  • 向下走,直到找到元素,否则你不能向左走
  • 如果当前元素小于被搜索的元素,则返回null(此迭代器已耗尽)
  • else返回当前元素

对于完全混合的类似大小的集合,这衰减到O(n1 + n2),如果第二棵树大得多,则衰减到O(n1 log n2)。如果一个树中的子树的范围不与另一个树/所有其他树中的任何节点相交,则访问该子树中的最多一个元素(其最小值)。这可能是最快的算法。

答案 1 :(得分:0)

这是一篇论文,其中包含有效的算法,用于查找AVL树的交叉点和联合(或其他类型的树以及其他操作)。

Implementing Sets Efficiently in a Functional Language

当我研究这个主题时,我发现了这篇论文。算法在Haskell中,它们主要是为不可变树设计的,但它们也适用于任何类型的树(尽管在某些语言中可能会有一些开销)。它们的性能保证与上面给出的算法类似。