【发布时间】:2014-09-17 05:07:55
【问题描述】:
所以我想知道在 Java 中最有效的合并排序实现是什么(以防它在时间方面的效率会因语言而异)。这个问题可能微不足道,但我的最终目标是向更有经验的程序员学习。这是我做的两个例子:
//version I made.
public static double[] mergeSort(double[] arreglo) {
if (arreglo.length > 1) {
int d = (arreglo.length / 2);
double[] arreglo1 = Arrays.copyOfRange(arreglo, 0, d),
arreglo2 = Arrays.copyOfRange(arreglo, d, arreglo.length);
arreglo1 = mergeSort(arreglo1);
arreglo2 = mergeSort(arreglo2);
return merge(arreglo1, arreglo2);
} else {
return arreglo;
}
}
public static double[] merge(double[] arreglo1, double[] arreglo2) {
double[] convi = new double[arreglo1.length + arreglo2.length];
for (int i = 0, m1 = 0, m2 = 0; i < convi.length; i++) {
if (arreglo1.length > m1 && arreglo2.length > m2) {
if (arreglo1[m1] <= arreglo2[m2])
convi[i] = arreglo1[m1++];
else {
convi[i] = arreglo2[m2++];
}
} else {
convi[i] = (arreglo1.length == m1) ? arreglo2[m2++] : arreglo1[m1++];
}
}
return convi;
}
//Taken out of Cormens book.
public static void mergeSort(int[] arreglo, int i, int f) {
if (f > i) {
int d = ((i + f) / 2);
mergeSort(arreglo, i, d);
mergeSort(arreglo, d + 1, f);
merge(arreglo, i, d, f);
}
}
public static void merge(int[] arreglo, int i, int m, int f) {
int n1 = (m - i) + 1;
int n2 = (f - m);
int[] mitad1 = new int[n1 + 1];
int[] mitad2 = new int[n2 + 1];
for (int v = 0; v < n1; v++) {
mitad1[v] = arreglo[i + v];
}
for (int p = 0; p < n2; p++) {
mitad2[p] = arreglo[p + m + 1];
}
mitad1[n1] = Integer.MAX_VALUE;
mitad2[n2] = Integer.MAX_VALUE;
for (int r = i, m1 = 0, m2 = 0; r <= f; r++) {
if (mitad1[m1] <= mitad2[m2]) {
arreglo[r] = mitad1[m1];
m1++;
} else {
arreglo[r] = mitad2[m2];
m2++;
}
}
}
【问题讨论】:
-
假设它们可以工作(而且它们看起来不错),这几乎肯定没关系。在大多数情况下,它们都将是
O(n log n)并且(通常)表现得比快速排序更差。一旦你看到更糟糕的情况,你会想知道为什么要花这么多时间来完善你的归并排序。 -
是的,感谢您的回答。我主要是想练习。
-
一个很好的通用技术是找到一个经常使用的库的源代码,它可以满足你的需求。 Java 库排序是一种稳定的归并排序,对几乎排序的列表进行了调整。许多聪明人付出了巨大的努力来减少许多架构上的运行时常数。一定要看看!
标签: java algorithm sorting mergesort