【问题标题】:Merging AVL trees using an empty tree (C++ templates)使用空树合并 AVL 树(C++ 模板)
【发布时间】:2011-08-07 06:54:19
【问题描述】:

作为我正在处理的 AVL 模板的一部分(C++ 模板),当 n1+n2 是两棵树中的总元素时,我试图以 O(n1+n2) 复杂度合并 2 棵 AVL 树。

我想到了下一个算法。

  1. 中序遍历第一棵树并构建一个数组/列表 - O(n1)
  2. 中序遍历第二棵树并构建一个数组/列表 - O(n2)
  3. 合并这 2 个数组的排序并构建最终排序的数组/列表,大小为 n1+n2 - O(n1+n2)
  4. 用 n1+n2 个顶点构建一个几乎完整的空二叉树 - O(n1+n2)。
  5. 在使用合并数组/列表中的元素更新顶点时,在几乎完整的二叉树上进行中序遍历。

我的问题是我如何实际构建具有 n1+n2 个顶点的几乎完整的空二叉树

【问题讨论】:

  • 请注意,如果您的树支持像 standard binary tree container 中的迭代器,您实际上可以直接执行第 3 步,而无需在中间存储中复制两棵树的节点。

标签: c++ data-structures merge binary-tree avl-tree


【解决方案1】:

如果将归并排序发出的节点存储在向量中,则可以相对容易地完成。您的节点已经排序,因此您可以按以下方式“插入”节点:

  1. 从数组 1/2 处的元素构建根节点;
  2. 使用数组 1/4 和 3/4 处的元素构建根的子节点;
  3. 递归重复 2。

这对您来说应该是按顺序遍历恰好被表示为排序数组的二叉树。

请注意,要使其正常工作,您需要在“关闭”平衡的情况下构建树。这很可能需要您将其设置为您的类的私有方法,可能是一个特殊的构造函数。

【讨论】:

  • 顺便说一下,这更像是第 4 步和第 5 步的组合。我不建议你构建“带有n1+n2 节点的空二叉树”。
  • 好主意,谢谢。我想它被认为比仅仅用 X 元素构建一个几乎完整的树更简单?此外,我的树中的每个顶点都包含一个字段,该字段表示左子树中有多少元素。如果以这种方式构建树,我将不得不在树已经完成后更新所有这些字段的中序遍历?
  • 当您拆分数组时,即使您还没有插入子节点,您也知道要在两边插入多少个节点。要么将其设置为该值,要么实际递归执行插入并在备份途中总结子节点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多