我担心为每个递归步骤创建3个数组可能会占用太多空间,但我真的无法找到另一种方法。请告诉我它有什么问题。
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
}
答案 0 :(得分:1)
您不需要创建多个临时数组来执行mergesort。你做错了就是复制数组以传递给递归调用;你应该传递原始数组。
查看JDK中mergesort的实现可能会提供信息 - 请参阅Arrays.java的第1146行。
答案 1 :(得分:0)
这是在顶层分配单个数组等于输入大小的代码,并将其重新用于所有递归。在一百万个整数上,这在我的机器上大约需要300毫秒,Java库排序需要230毫秒。好吧没有调整工作,我猜......
// 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]);
}