如何合并两个二叉搜索树保持BST的财产?
如果我们决定从树上取每个元素,并将其插入到另一个中,这种方法的复杂性是O(n1 * log(n2))
其中n1
是树的节点的数量(比如T1
),其我们已经分裂,而n2
是其他树的节点的数量(比如T2
)。 此操作后只有一个BST有n1 + n2
节点。
我的问题是:我们可以做任何为O更好(N1 *日志(N2))?
如何合并两个二叉搜索树保持BST的财产?
如果我们决定从树上取每个元素,并将其插入到另一个中,这种方法的复杂性是O(n1 * log(n2))
其中n1
是树的节点的数量(比如T1
),其我们已经分裂,而n2
是其他树的节点的数量(比如T2
)。 此操作后只有一个BST有n1 + n2
节点。
我的问题是:我们可以做任何为O更好(N1 *日志(N2))?
Naaff的答案多一点细节:
三步O(N1 + N2),结果在O(N1 + N2)
对于大小的顺序相同的N1和N2,这是为O更好(N1 *日志(N2))
[1]算法从排序列表(在Python)创建平衡BST:
def create_balanced_search_tree(iterator, n):
if n == 0:
return None
n_left = n//2
n_right = n - 1 - n_left
left = create_balanced_search_tree(iterator, n_left)
node = iterator.next()
right = create_balanced_search_tree(iterator, n_right)
return {'left': left, 'node': node, 'right': right}
IIRC,这是O(N1 + N2)。
什么树都压扁成排序的列表,合并列表,然后创建一个新的树?
乔纳森,
排序后,我们有长度N1 + N2的列表。 建立二叉树出它需要登录(N1 + N2)的时间。 这是一样的归并排序,只是在每个递归步骤,我们不会有一个O(N1 + N2)项,因为我们有在归并排序算法。 所以,时间复杂度是log(N1 + N2)。
现在整个问题的复杂度为O(N1 + N2)。
此外,我会说这做法是好的,如果两个列表是规模相当。 如果大小是没有可比性的话,就最好到小树上的每一个节点插入到一棵大树。 这将需要O(N1 *日志(N2))的时间。 例如,如果我们有两棵树的大小10的一个又一个的尺寸1024,这里N1 + N2 = 1034,其中作为n1log(N2)= 10 * 10 = 100。因此,方法必须依赖于两棵树的大小。
O(N1 *日志(N2))是平均的情况下,即使我们有2个合并任何无序列表为BST。 我们没有利用的事实,列表进行排序列表或BST。
据我让我们假设一个BST有N1元素和其他具有N2的元素。 现在转换一个BST成一个有序数组列表L1在O(N1)。
合并BST(BST,阵列)
如果(Array.size == 0)返回BST如果(Array.size == 1)插入在BST的元素。 返回BST;
查找其左元素<BST.rootnode和右元素> = BST.rootnode说索引阵列中的索引。 如果(BST.rootNode.leftNode == NULL)//即没有左节点{插入所有从索引阵列为0到左BST的和}否则{合并BST(BST.leftNode,数组{0至索引})}
如果(BST.rootNode.rightNode == NULL)//即没有右节点{插入所有从索引阵列Array.size成BST的右}否则{合并BST(BST.rightNode,数组{索引Array.size} )}
返回BST。
该算法将<<时间为O(N *日志(N2))为每一个我们正在分割阵列和BST来处理子问题的时间。
我们的想法是使用迭代序遍历。 我们使用两个辅助栈两个BSTS。 由于我们需要打印排序的形式要素,每当我们从任何树木得到一个更小的元素,我们打印出来。 如果该元素是更大的,那么我们将其推回堆栈进行下一次迭代。