简体   繁体   English

这是mergesort的正确实现吗?

[英]Is this a proper implementation of mergesort?

I'm worried that the creation of 3 arrays for every recursion step might take up too much space, but I really couldn't figure out another way of doing it. 我担心为每个递归步骤创建3个数组可能会占用太多空间,但是我真的想不出另一种方法。 Please tell me whatever is wrong with it. 请告诉我它有什么问题。

public static int[] split(int [] vector){

    if(vector.length <= 1 || vector == null) 
        return vector;
    int len = vector.length;

    int[] list1 = new int[len / 2];
    // If the number of elements is odd the second list will be bigger
    int[] list2 = new int[len / 2 + (len % 2)];

    // Here we assign the elements to 2 separate lists
    for(int x = 0; x < len / 2; x++)
        list1[x] = vector[x];
    for(int j = 0, i = len / 2; j < list2.length; i++, j++)
        list2[j]=vector[i];

    // Apply the recursion, this will eventually order the lists
    list1 = split(list1);
    list2 = split(list2);

    // Here we take the 2 ordered lists and merge them into 1
    int i = 0, a = 0, b = 0;
    int[] listfinal = new int[len];
    while(i < len){
        if(a >= list1.length){
            listfinal[i] = list2[b]; 
            b++;
        } else if(b >= list2.length){
            listfinal[i] = list1[a]; 
            a++;
        } else if(list1[a] <= list2[b]){
            listfinal[i] = list1[a]; 
            a++;
        } else if(list1[a] > list2[b]){
            listfinal[i] = list2[b]; 
            b++;
        }
        i++;
    }
    return listfinal; // Return the merged and ordered list
}

You shouldn't need to create more than one temporary array to do mergesort. 您不需要创建多个临时数组即可进行mergesort。 What you're doing wrong is copying the arrays to pass to the recursive invocation; 您在做错了什么,就是复制数组以传递给递归调用。 you should instead pass the original array. 您应该改为传递原始数组。

It may be informative to look at the implementation of mergesort in the JDK - look on line 1146 of Arrays.java . 在JDK中查看mergesort的实现可能会很有帮助,请看Arrays.java第1146

Here is code that allocates a single array equal to the input size at the top level and re-uses it for all the recursion. 这是在顶层分配等于输入大小的单个数组并将其用于所有递归的代码。 On a million integers, this takes about 300 ms on my machine and the Java library sort takes 230 ms. 以一百万个整数计,这在我的机器上大约需要300毫秒,而Java库排序则需要230毫秒。 Okay for no tuning effort, I guess... 好吧,我不做任何调整,我想...

// Sort the elements of a between lo and hi inclusive.
private static void sortImpl(int [] a, int lo, int hi, int [] tmp) {

    if (hi <= lo) return;

    // Recur on sublists.
    int mid = (hi + lo) / 2;
    sortImpl(a, lo, mid, tmp);
    sortImpl(a, mid + 1, hi, tmp);

    // Move past items already in the right place.
    int t1 = lo;
    while (a[t1] < a[mid + 1]) t1++;

    // Merge sublists into result.
    int p1 = t1;
    int p2 = mid + 1;
    int i = t1;
    System.arraycopy(a, t1, tmp, t1, mid - t1 + 1);
    while (p1 <= mid)
        a[i++] = (p2 > hi || tmp[p1] < a[p2]) ? tmp[p1++] : a[p2++];
}

public static void sort(int [] a) {
    sortImpl(a, 0, a.length - 1, new int[a.length]);
}

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

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