algorithm - 从二叉搜索树构建 AVL 树

标签 algorithm data-structures time-complexity binary-search-tree avl-tree

我需要建议一种算法,该算法采用 BST(二叉搜索树)、具有 2^(n + 1) - 1 键的 T1 并构建 AVL具有相同键的树。该算法在最差时间复杂度和平均时间复杂度(作为 n 的函数)方面应该是有效的。

我不知道应该如何处理这个问题。很明显,具有 2^(n + 1) - 1 键的 BST 的最小大小是 n (如果它已满/平衡),但是它对我有什么帮助?

有一种直接的方法,即迭代树,每次将 T1 的根添加到 AVL 树,然后将其从 T1 中删除:

  • 由于 T1 可能不平衡,因此在最坏情况下删除可能会花费 O(n)
  • 插入 AVL 的成本为 O(log n)
  • 2^(n + 1) - 1

所以总共花费O(n*logn*2^n),而且贵得离谱。

但是为什么我应该从 T1 中删除?我在那里付了很多钱,而且没有什么充分的理由。 所以我想为什么不使用 T1 上的树遍历,并且对于我访问的每个节点,将其添加到 AVL 树中:

  • 2^(n + 1) - 1 个节点,因此遍历将花费 O(2^n)(访问每个节点一次)
  • 每次将当前节点添加到 AVL 都会花费 O(logn)

所以总共花费O(logn * 2^n)。 这是我能想到的最好的时间复杂度,问题是,能以更快的方式完成吗?就像O(2^n) 一样? 有什么方法可以使插入 AVL 树的成本仅为 O(1)?

我希望我说得很清楚,我的问题属于这里。

非常感谢,

诺姆

最佳答案

有一种平衡 BST 并以线性时间运行的算法,称为 Day Stout Warren Algorithm

基本上,它所做的就是通过中序遍历 (O(n)) 将 BST 转换为排序数组或链表。然后,它递归地获取数组的中间元素,使其成为根,并使其子数组分别成为左右子数组的中间元素(O(n))。这是一个例子,

       UNBALANCED BST
            5
          /   \
         3     8
              / \
             7   9
            /     \
           6      10


        SORTED ARRAY
      |3|5|6|7|8|9|10|

现在这是递归调用和生成的树,

 DSW(initial array)

             7
 7.left = DSW(left array) //|3|5|6|
 7.right = DSW(right array) //|8|9|10|

             7
            / \
           5   9
 5.left = DSW(|3|)
 5.right = DSW(|6|)
 9.left = DSW(|8|)
 9.right = DSW(|10|)

             7
            / \
           5   9
          / \ / \
         3  6 8 10

关于algorithm - 从二叉搜索树构建 AVL 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38189001/

相关文章:

algorithm - 图作为邻接矩阵时间复杂度

python - 寻找一种有效的方法或算法来检查文件是否属于某个文件夹路径列表中的某个项目

c++ - 指向类的指针

algorithm - 寻找一个完美的英文 Pangram 算法

algorithm - 如何在数据流中找到循环/重复?

Python append() 只允许列表中的唯一项?

algorithm - O(nlogn) + O(n) 的时间复杂度是否只是 O(nlogn)?

c++ - 找到两个数字的公约数最多为 10^6 的最有效方法

计算两次之间差异所需的算法

c - 给定一个无序列表,返回列表中不存在的值