最近我在Mergesort中测试了两种合并方法的变体,其中一种变形比另一种略快。对于足够大的输入(例如,一个1000到1亿或更多随机排序元素的数组),一种合并方法比另一种方法花费大约100ms。
这是一个花费更多时间的人:
private static void merge(int[] a, int low, int mid, int hi) {
int temp[] = new int[(hi - low) + 1];
int cLeft = low;
int cRight = mid + 1;
int cTemp = 0;
while (cLeft <= mid && cRight <= hi) {
if (a[cLeft] <= a[cRight]) {
temp[cTemp++] = a[cLeft++];
} else {
temp[cTemp++] = a[cRight++];
}
}
//copy the remaining left elements to the right end
System.arraycopy(a, cLeft, a, low + cTemp, mid - cLeft + 1);
//copy temp to a
System.arraycopy(temp, 0, a, low, cTemp);
}
......这是更快的
private static void merge(int[] list, int lowIndex, int midIndex, int highIndex) {
int[] L = new int[midIndex - lowIndex + 2];
for (int i = lowIndex; i <= midIndex; i++) {
L[i - lowIndex] = list[i];
}
L[midIndex - lowIndex + 1] = Integer.MAX_VALUE;
int[] R = new int[highIndex - midIndex + 1];
for (int i = midIndex + 1; i <= highIndex; i++) {
R[i - midIndex - 1] = list[i];
}
R[highIndex - midIndex] = Integer.MAX_VALUE;
int i = 0, j = 0;
for (int k = lowIndex; k <= highIndex; k++) {
if (L[i] <= R[j]) {
list[k] = L[i];
i++;
} else {
list[k] = R[j];
j++;
}
}
}
MergeSort的两个变体都被赋予不同的相同长度的数组,相同的元素与它们的输入位于相同的位置。换句话说,一种算法的输入是另一种算法的输入的副本。
尽管运行时间的差异可以忽略不计(平均运行时间不会改变,即无论我们在100万标记后增加多少,都会保持100毫秒。),我很想知道是什么让速度更快{ {1}}更快。对我来说,前一种方法更简洁,更容易实现。但是,如果另一个保持更快,我可能会切换到那个。