繁体   English   中英

合并排序比较?

[英]Merge sort comparisons?

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

    }

    }

你得到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
}

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

您显示的比较次数对于您给我们的方法是正确 当长度为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 ,因此在调用one之后, comp=2 ,并且在调用two之后, comp=4 然而,这些递归调用中的每一个都会进行两次递归调用,因为在每次调用中, min==max ,该方法返回return comp; ,永远不会到达增加comp的线。

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

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

/* 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的单行更改。 我的代码按预期工作,我没有看到相同的结果。 也许其他事情被意外改变了?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM