我有几个关于插入排序的不同实现的问题。
实施1:
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
int key = a[i];
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
--j;
}
a[j + 1] = key;
}
}
实施2:
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
for (int j = i; j > 0 && a[j - 1] > a[j]; --j) {
swap(a, j, j - 1);
}
}
}
private static void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
这是我的第一个问题:人们应该认为第一个版本应该比第二个版本快一点(因为分配较少),但事实并非如此(或者至少差异可以忽略不计)。但为什么?
其次,我想知道Java的 Arrays.sort() 方法也使用了第二种方法(可能是因为代码重用,因为在不同的地方使用了 swap 方法,可能是因为它更容易理解)。
实现3(binaryInsertionSort):
public static void binaryInsertionSort(int[] a) {
for (int i = 1; i < a.length; ++i) {
int pos = Arrays.binarySearch(a, 0, i, a[i]);
int insertionPoint = (pos >= 0) ? pos : -pos - 1;
if (insertionPoint < i) {
int key = a[i];
// for (int j = i; i > insertionPoint; --i) {
// a[j] = a[j - 1];
// }
System.arraycopy(a, insertionPoint, a, insertionPoint + 1, i - insertionPoint);
a[insertionPoint] = key;
}
}
}
二进制插入类型是否有任何实际用途,还是更像是一种理论上的东西?在小数组上,其他方法要快得多,而在更大的数组上,mergesort/quicksort 的性能要好得多。