Важнее, чем оптимизация, вы должны сначала достичь правильности. В методе increasing
stati c есть ошибка: если размер аргумента массива не является четным, подмассив right
имеет неправильный размер: int[] right = new int[q];
должно быть
int[] right = new int[arr.length - q];
Кроме того, вы не должны пытаться разделить массив, если он слишком мал.
Что касается оптимизации, вы должны отступать до InsertionSort()
только тогда, когда размер подмассива ниже порога, где-то между 16 и 128 элементами , Тщательный бенчмаркинг с различными пороговыми значениями и различными распределениями поможет определить хороший порог для вашей системы.
В настоящее время ваша функция имеет временную сложность O (N 2 ). ) , потому что это относится к InsertionSort
для всех, кроме последней фазы слияния. Чтобы уменьшить сложность до O (N.log (N)) , вы должны выполнять возврат на подмассивах до тех пор, пока их размер не станет ниже фиксированного порога.
Вот измененная версия:
package com.algorithms.sort;
public class MergeSort {
public static int threshold = 32;
public static int[] increasing(int[] arr) {
if (arr.length <= threshold)
return InsertionSort.increasing(arr);
int len1 = arr.length / 2;
int[] left = new int[len1];
for (int i = 0; i < len1; i++) {
left[i] = arr[i];
}
int len2 = arr.length - len1;
int[] right = new int[len2];
for (int i = 0; i < len2; i++) {
right[i] = arr[i + len1];
}
left = increasing(left);
right = increasing(right);
int[] result = new int[len1 + len2];
int i = 0;
int j = 0;
int s = 0;
while (i < len1 && j < len2) {
if (left[i] <= right[j]) {
result[s] = left[i];
i++;
} else {
result[s] = right[j];
j++;
}
s++;
}
while (i < len1) {
result[s] = left[i];
i++;
s++;
}
while (j < len2) {
result[s] = right[j];
j++;
s++;
}
return result;
}
/**
* Main method to test an example integer array
*/
public static void main(String[] args) {
int[] ar = { 18, 12, 11, 6, 55, 100 };
int[] res = increasing(ar);
for (int a : res) {
System.out.print(a + " ");
}
}
}