【发布时间】:2018-04-19 06:54:30
【问题描述】:
我目前正在为学校开展一个项目,该项目要求我为不同的排序算法编写代码。最困难的部分是在给定长度为 2^N 的输入数组的情况下编写合并排序的迭代版本。我使用了一个名为 merge 的必需辅助方法来帮助迭代合并。
我的结构如下。给定一个 2^N 的数组(让我们使用 16 的数组大小来解释我的方法),我遍历数组查看每个 2 个整数,并使用 merge() 交换一个大于另一个的整数。这个过程将在长度为 16 的数组中发生 8 次。然后,我将遍历数组,查看每个 4 个整数 4 次。我会使用我的合并方法来合并每组 4 个中的两个有序对。然后,我会查看一个由 8 个整数组成的块……依此类推。我的代码贴在这里:
public static void MergeSortNonRec(long[] a) {
//======================
//FILL IN YOUR CODE HERE
//======================
/*
System.out.print("Our array is: ");
printArray(a);
System.out.println('\n');
*/
int alength = a.length;
int counter = 2;
//the counter will iterate through levels 2n - 2 4 8 16 32 etc.
int pointtracker = 0;
//the point tracker will keep track of the position in the array
while (counter <= alength) {
long [] aux = new long [alength];
int low = pointtracker;
int high = pointtracker + counter - 1;
int mid = (low + high)/2;
merge(a, aux, low, mid, high);
if (high < alength - 1) {
pointtracker += counter;
//move to the next block
}
else {
//if our high point is at the end of the array
counter *= 2;
pointtracker = 0;
//start over at a[0], with a doubled counter
}
}
/*
System.out.print("Final array is: ");
printArray(a);
System.out.println('\n');
*/
}//MergeSortNonRec()
我的合并方法如下:
private static void merge(long[] a, long[] aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
// merge back to a[]
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (aux[j] < aux[i]) a[k] = aux[j++];
else a[k] = aux[i++];
}
}
递归解决方案更加优雅:
private static void sort(long[] a, long[] aux, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid + 1, hi);
merge(a, aux, lo, mid, hi);
}
public static void MergeSort(long[] a) {
long[] aux = new long[a.length];
sort(a, aux, 0, a.length-1);
}
我的问题是运行时。我的教授说合并排序的迭代版本,因为我们只输入长度为 2^N 的数组,应该比非迭代版本运行得更快。但是,我的迭代版本运行速度比大型集合中的递归版本慢。这是我的时间输出示例:
![runtime]: https://imgur.com/a/bzVuw "排序算法"
我可以做些什么来减少迭代归并排序的时间?
编辑:我想通了。我将我的 aux 实例移到了 while 循环之外,这以指数方式减少了时间。谢谢大家!
【问题讨论】:
标签: java arrays sorting merge mergesort