【问题标题】:Building an AVL Tree out of Binary Search Tree从二叉搜索树构建 AVL 树
【发布时间】:2016-11-06 10:31:53
【问题描述】:

我需要建议一种算法,该算法采用 BST(二叉搜索树)T1,具有 2^(n + 1) - 1 键,并构建具有相同键的 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)?

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

非常感谢,

诺姆

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • @Noam 没问题,如果您发现答案有帮助,请不要忘记将其标记为已接受。祝你编码好运!
    • 会的。如果我的问题清晰有用,你也可以给我+1。
    猜你喜欢
    • 2016-01-07
    • 2013-01-18
    • 2016-02-03
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多