我有幾個關於插入排序實現的問題。InsertionSort與InsertionSort與BinaryInsertionSort
實現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具有更好的性能。
我猜測這種差異可以忽略不計,因爲:對於小型陣列,所花費的全部時間可以忽略不計;對於大型陣列,所花費的時間由緩存性能決定。由於第二個版本中的額外寫入與兩個版本所做的寫入相鄰,因此第二個版本不需要訪問任何額外的高速緩存行,因此性能不受影響。這只是一個猜測,但是,甚至有可能您的JIT已經將它們優化爲或多或少相同,並且如果性能存在差異,我也不會感到驚訝。 – 2010-01-28 12:34:54