假设我有两个AVL树,并且第一个树中的每个元素都小于第二个树中的任何元素。将它们连接成一个单独的AVL树的最有效方法是什么?我到处搜索,但没有找到任何有用的东西。
答案 0 :(得分:30)
假设你可能会破坏输入树:
因此,整个操作可以在O(log n)中执行。
编辑:第二个想法,在下面的算法中更容易推理旋转。它也可能更快:
left
树中删除最右边的元素(必要时旋转并调整其计算高度)。让n
成为该元素。 O(log n)left
高1。让r
成为该节点。 O(log n)用值为n的新节点替换该节点,并使用子树left
和r
替换。 O(1)
通过构造,新节点是AVL平衡的,其子树1高于r
。
相应地增加其父母的余额。 O(1)
答案 1 :(得分:5)
一个超简单的解决方案(在树之间的关系中没有任何假设的情况下工作)是:
这两个步骤都是O(n)。它的主要问题是需要额外的O(n)空间。
答案 2 :(得分:4)
我可以找到我对这个问题的最佳解决方案here。如果你纠正这个问题,非常接近meriton的答案:
在算法的第三步中,向左导航,直到到达子树与左树的高度相同的节点。这并不总是可行的(参见反例图像)。执行此步骤的正确方法是找到高度为h
或h+1
的子树,其中h
是左树的高度
答案 3 :(得分:1)
我怀疑你只需要走一棵树(希望更小),然后将每个树的元素分别添加到另一棵树上。 AVL插入/删除操作不是为处理一次添加整个子树而设计的。