从二叉搜索树构建 AVL 树

Building an AVL Tree out of Binary Search Tree

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

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

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

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

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

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

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

非常感谢,

诺姆

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

基本上它所做的就是通过 in-order 遍历 (O(n)) 将 BST 转换为排序数组或链表。然后,它递归地取数组的中间元素,使它成为根,并使其children分别成为左右子数组的中间元素(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