📅  最后修改于: 2023-12-03 15:22:57.717000             🧑  作者: Mango
排序树是一种有序的数据结构,其中每个节点都包含一个值,使得左子节点上的值小于父节点上的值,而右子节点上的值大于父节点上的值。排序树中最常用的一种是二叉搜索树(BST)。类似于BST,合并排序树(MST)是一种有序树,其中每个节点都可以包含多个元素,而在每个节点中存储的元素是按顺序排列的。 M ST通过在排序树中添加两个重要操作来扩展标准BST:分割操作和合并操作。
给定一个MST T和一个元素x,分割操作将M ST T划分为三个M ST,分别包含小于,等于和大于x的元素。这可以通过对T进行拆分和重构来实现。
public static void split(MergeSortTree T, Comparable x, MergeSortTree[] leftTree,
MergeSortTree[] eqTree, MergeSortTree[] rightTree) {
if (T == null) {
MergeSortTree[] emptySet = { null };
leftTree[0] = emptySet[0];
eqTree[0] = emptySet[0];
rightTree[0] = emptySet[0];
}
else {
int cmp = T.min().compareTo(x);
if (cmp > 0) {
split(T.left, x, leftTree, eqTree, new MergeSortTree[] { T });
rightTree[0] = T.right;
}
else if (cmp < 0) {
split(T.right, x, new MergeSortTree[] { T }, eqTree, rightTree);
leftTree[0] = T.left;
}
else // T.min() == x
{
MergeSortTreeNode[] emptySet = { null };
eqTree[0] = new MergeSortTree(new MergeSortTreeNode(x, emptySet[0]));
leftTree[0] = T.left;
rightTree[0] = T.right;
}
}
}
从代码中可以看出,如果x小于当前节点中的最小值,则递归地分割左子树;如果x大于当前节点中的最小值,则递归地分割右子树。不幸的是,并非所有节点都包含x。如果x不在树中,则需要subclassMIT一个MST,其中eqTree是一棵只包含元素x的树。
给定两个 MS T T1和 T2,合并操作将它们合并为一个新的M ST T。这可以通过查找它们的最小值并将它们的“左”和“右”子树相应地递归到下一个级别来实现。
public static MergeSortTree meld(MergeSortTree T1, MergeSortTree T2) {
if (T1 == null) {
return T2;
}
if (T2 == null) {
return T1;
}
if (T1.min().compareTo(T2.min()) <= 0) {
MergeSortTreeNode[] emptySet = { null };
MergeSortTree[] rightTree = { null };
split(T2, T1.min(), new MergeSortTree[] { null },
new MergeSortTree[] { null }, rightTree);
return new MergeSortTree(new MergeSortTreeNode(T1.min(),
new MergeSortTree[] { T1.left, rightTree[0] }));
}
else {
return meld(T2, T1);
}
}
从代码中可以看出,如果T1为空,则返回T2;如果T2为空,则返回T1。然后,它比较T1的最小值和T2的最小值,将它们分为两个组:小于或等于T1的最小值的所有元素放在它的左子树中,而大于T1的最小值的所有元素放在其右子树中。然后,递归地调用融合来合并子树。