合并排序比较?

时间:2013-09-09 01:49:33

标签: java arrays sorting mergesort

我不认为使用合并排序的比较次数在我的合并排序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;

    }

    }

2 个答案:

答案 0 :(得分: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次比较

merge sort是一种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
}

第二次调用排序将使用排序数据而不是未排序数据,这样您就可以获得 不同的结果。对数组进行排序可以修改数组,从而调用sort数组 时间可以得到不同的行为。

答案 1 :(得分: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

在每次调用完成两次额外的嵌套递归调用之后,它们继续将comp递增2,因为for循环运行的迭代次数等于size。在这两个来电中都是size=2,所以在调用一个comp=2之后,以及在调用二之后,comp=4。 然而,这些递归调用中的每一个都会进行两次递归调用,因为在每次调用min==max中,该方法都会返回return comp;,永远不会到达增加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

希望我在这里清楚明白了!

edit1: BevynQ的回答是正确的。我的回答更多地关注为什么你的代码返回8 ,而他的回答集中在为什么你的排序方法错误地计算比较

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