0

我认为在返回比较次数的合并排序 2 类/方法中使用合并排序的比较次数不正确。合并排序 2 类似于合并排序,但只返回比较的数量。下面是我的演示,我有一个包含 4 个整数 {2,55,1,45} 的数组,当我运行程序时它返回 8 个比较。谁能验证这是否正确或我做错了什么?

我的演示:

    ArrayInts[] myInts2 = new ArrayInts[4];

    myInts2[0] = new ArrayInts(2);
    myInts2[1] = new ArrayInts(55);
    myInts2[2] = new ArrayInts(1);
    myInts2[3] = new ArrayInts(45);

    MergeSort.mergeSort(myInts2, 0, 3);

    System.out.println("Sorted using Merge Sort: ");


    for (int index = 0; index < myInts2.length; index++) {
        System.out.println(myInts2[index]);
    }

    System.out.println("Number of comps using Merge Sort: " + MergeSort2.mergeSort2(myInts2, 0, 3));
    System.out.println(" ");

我的合并排序 2 类/方法:

 public class MergeSort2 {
 private static long comp=0;

public static <T extends Comparable<? super T>> long mergeSort2(T[] data, int min, int max) {
    T[] temp;
    int index1, left, right;


    //return on list of length one

    if (min == max) {
        return comp;
    }

    //find the length and the midpoint of the list

    int size = max - min + 1;
    int pivot = (min + max) / 2;
    temp = (T[]) (new Comparable[size]);

    mergeSort2(data, min, pivot); //sort left half of list
    mergeSort2(data, pivot + 1, max); //sort right half of list

    //copy sorted data into workspace

    for (index1 = 0; index1 < size; index1++) {
        temp[index1] = data[min + index1];
    }

    //merge the two sorted lists

    left = 0;
    right = pivot - min + 1;
    for (index1 = 0; index1 < size; index1++) {
        comp++;
        if (right <= max - min) {

            if (left <= pivot - min) {

                if (temp[left].compareTo(temp[right]) > 0) {

                    data[index1 + min] = temp[right++];
                } else {
                    data[index1 + min] = temp[left++];
                }
            } else {
                data[index1 + min] = temp[right++];
            }
        } else {
            data[index1 + min] = temp[left++];
        }
    }


    return comp;

    }

    }
4

2 回答 2

2

你得到 8 因为你每次合并循环执行时都会增加,无论是否有比较。

如果你改变

for (index1 = 0; index1 < size; index1++) {
    comp++;
    if (right <= max - min) {

        if (left <= pivot - min) {

for (index1 = 0; index1 < size; index1++) {
    if (right <= max - min) {

        if (left <= pivot - min) {
            comp++;

您将获得比较次数而不是循环迭代次数。

[0,1,2,3] 应该产生 4 个比较
[3,2,1,0] 应该产生 4 个比较
[0,2,1,3] 应该产生 5 个比较
[0,4,1,5,2, 6,3,7] 应该产生 16 个比较

归并排序是一个 O(nlog2n) 最坏情况算法。

您还需要更改此位

MergeSort.mergeSort(myInts2, 0, 3);

System.out.println("Sorted using Merge Sort: ");


for (int index = 0; index < myInts2.length; index++) {
    System.out.println(myInts2[index]);
}

System.out.println("Number of comps using Merge Sort: " + MergeSort2.mergeSort2(myInts2, 0, 3));
System.out.println(" ");

int result = MergeSort.mergeSort(myInts2, 0, 3);

System.out.println("Sorted using Merge Sort: ");


for (int index = 0; index < myInts2.length; index++) {
    System.out.println(myInts2[index]);
}

System.out.println("Number of comps using Merge Sort: " + result);
System.out.println(" ");

因为 myInts 将在您输出计数时进行排序,因此您可以获得排序的复杂性。

演示多次调用 sort 的效果。

public static void main(String[] args) {
    Integer[] myInts2 = new Integer[4];

    myInts2[0] = new Integer(0);
    myInts2[1] = new Integer(2);
    myInts2[2] = new Integer(1);
    myInts2[3] = new Integer(3);

    System.out.println(new MergeSort2().mergeSort2(myInts2, 0, 3)); // will output 5
    System.out.println(new MergeSort2().mergeSort2(myInts2, 0, 3)); // will output 4
}

再次调用排序将使用已排序的数据而不是未排序的数据,因此您将获得不同的结果。对数组进行排序可以修改数组,因此多次调用排序可以获得不同的行为。

于 2013-09-09T02:08:24.967 回答
0

您显示的比较次数与您提供给我们的方法是正确的。当一个长度数组4被传递给你给我们的方法时,该行comp++;被调用了 8 次。让我解释。

首先,pivot=1。这些行进行了两次递归调用:

mergeSort2(data, min, pivot); //sort left half of list
mergeSort2(data, pivot + 1, max); //sort right half of list

在这些调用中的每一个完成它们的两个额外的嵌套递归调用之后,它们继续递增comp2,因为 for 循环运行的迭代次数等于size. 在这两个电话中,size=2,所以在电话一之后comp=2, 和电话二之后,comp=4。然而,这些递归调用中的每一个又会再进行两次递归调用,因为在这些调用中的每一个中min==max,方法都返回 on return comp;,永远不会到达要 increment 的行comp

最后,在两个初始递归方法调用返回后,for 循环自增comp又被调用了四次,因为在初始调用中,size=4. 因此, comp = 4 + 4, 等于 8!

如果这令人困惑,我将用每次调用的 ( min, ) 来说明我的答案。maxmergesort2()

/* 1. */ (min=0, max=3) -> size=4, comp = comp + 4;
/* 2. */     (min=0, max=1) -> size=2, comp = comp + 2;
/* 3. */         (min=0, max=0) -> size=0, comp = comp + 0;
/* 4. */         (min=1, max=1) -> size=0, comp = comp + 0;
/* 5. */     (min=2, max=3) -> size=2, comp = comp + 2;
/* 6. */         (min=2, max=2) -> size=0, comp = comp + 0;
/* 7. */         (min=3, max=3) -> size=0; comp = comp + 0;

/* TOTAL. */  comp = 0 + 0 + 2 + 0 + 0 + 2 + 4; comp = 8

希望我在这里说清楚了!

编辑1: BevynQ 的回答是正确的。我的回答更侧重于您的代码返回 8 的原因,而他的回答侧重于您的排序方法错误地计算比较的原因。

edit2:我将您的代码直接复制并粘贴到我的编辑器中,并进行了 BevynQ 添加的一行更改。我的代码按预期工作,我没有看到与您相同的结果。也许其他东西被意外改变了?

于 2013-09-09T02:24:16.913 回答