У меня есть пара вопросов, касающихся различных вариантов сортировки вставки.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() также использует второй подход (возможно, из-за повторного использования кода, потому что метод подкачки используется в разных местах, возможно, потому, что это проще понять).
Реализация 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 оптимизировал их, чтобы быть более или менее одинаковыми, и в равной степени я бы не удивился, если бы была разница в производительности. –