使用应该相同的变量时的两个不同答案(mergeSort)

时间:2017-10-22 05:27:17

标签: java arrays sorting recursion mergesort

我有点困惑,正在寻找一些澄清,所以我正在研究数据结构和算法,并正在进行合并排序。基本上我想返回排序列表并打印它以测试我是否正确实现了代码,但懒惰的科学家我决定不将数据复制回原始数组而只是返回临时数组。我注意到,当我最后返回temp时,我会得到一个不同的答案,就像我在复制后返回原始数组(命名为a)一样。想知道是否有人能解释为什么会这样。谢谢!下面是具有正确打印的代码,如果您在合并方法中将返回值更改为temp,您会注意到列表正在正确排序

public class mergeSort {

public static void main(String[] args) {

    int[] a = new int[10];

    for(int i = 0; i < a.length; i++) {

        a[i] = (int)(Math.random()*30+1);
        System.out.println(i + ": " + a[i]);
    }

    mergeSort(a);
}

public static void  mergeSort(int[] a) {


    int[] temp = new int[a.length];

    a = mergeSort(a, 0, a.length, temp);

    for(int i = 0; i < a.length; i++){

        System.out.println(a[i]);
    }

}

public static int[] mergeSort(int[] a, int start, int end, int[] temp) {

    int mid;


    //Recursive method
    if(1 < end-start) {

        mid = start + (end-start)/2;
        mergeSort(a, start, mid, temp);
        mergeSort(a, mid, end, temp);
        a = merge(a, start, mid, end, temp);
    }

    return a;


}

public static int[] merge(int[] a, int start, int mid, int end, int[] temp) {


    int currL = start;
    int currR = mid;
    int currT;

    for(currT = start; currT < end; currT++) {

        if(currL < mid && (currR >= end || a[currL] < a[currR])) {

            temp[currT] = a[currL];
            currL++;
        }

        else{

            temp[currT] = a[currR];
            currR++;
        }

    }

    for(currT = start; currT < end; currT++) {
        a[currT] = temp[currT];
    }

    return a;

} 
}

1 个答案:

答案 0 :(得分:1)

考虑:

mergeSort(a, 0, 10, temp);

它叫:

mergeSort(a, 0, 5, temp);
mergeSort(a, 5, 10, temp);
a = merge(a, 0, 5, 10, temp);

mergeSort(a, 0, 5, temp)返回后,必须对子数组a [0]到[5]进行排序,并在mergeSort(a, 5, 10, temp)返回后,子数组a [5]到a [10]必须排序。

如果merge未修改原始数组a,则不会发生这种情况。

请注意,赋值a = merge(a, start, mid, end, temp);不会更改传递给mergeSort方法的原始数组。因此,merge本身必须修改传递给它的数组a,方法是将temp数组中的数据复制回a

编辑:

BTW,请注意,只要将merge数组中的合并元素复制回temp数组,a返回的内容无关紧要。

您可以将其返回类型更改为void,排序仍然有效:

public static void mergeSort(int[] a, int start, int end, int[] temp) {
    int mid;
    //Recursive method
    if(1 < end-start) {
        mid = start + (end-start)/2;
        mergeSort(a, start, mid, temp);
        mergeSort(a, mid, end, temp);
        merge(a, start, mid, end, temp);
    }  
}

public static void merge(int[] a, int start, int mid, int end, int[] temp) {
    int currL = start;
    int currR = mid;
    int currT;

    for(currT = start; currT < end; currT++) {
        if(currL < mid && (currR >= end || a[currL] < a[currR])) {
            temp[currT] = a[currL];
            currL++;
        } else {
            temp[currT] = a[currR];
            currR++;
        }
    }
    for(currT = start; currT < end; currT++) {
        a[currT] = temp[currT];
    } 
}