Сортировка слиянием (рекурсивная и нерекурсивная версии)
- private static int[] sortMerge(int[] arr) {
- int len = arr.length;
- if (len < 2)
- return arr;
- int middle = len / 2;
- return merge(sortMerge(Arrays.copyOfRange(arr, 0, middle)),
- sortMerge(Arrays.copyOfRange(arr, middle, len)));
- }
- private static void sortMergeNoRecursive(int[] arr) {
- int len = arr.length;
- int n = 1; // кратность сравнений (сравнивать по 1-му елем., двум
- int shift; // сдвиг в перебираемом массиве
- int two_size;// количество елементов для 2-го массива
- int[] arr2;
- while (n < len) {
- shift = 0;
- while (shift < len) {
- if (shift + n >= len)
- break;
- two_size = (shift + n * 2 > len) ? (len - (shift + n)) : n;
- arr2 = merge(
- Arrays.copyOfRange(arr, shift, shift + n),
- Arrays.copyOfRange(arr, shift + n, shift + n + size));
- for (int i = 0; i < n + two_size; ++i)
- arr[shift + i] = arr2[i]; // замена на отсортрованное
- shift += n * 2;
- }
- n *= 2;
- }
- }
- private static int[] merge(int[] arr_1, int[] arr_2) {
- int len_1 = arr_1.length, len_2 = arr_2.length;
- int a = 0, b = 0, len = len_1 + len_2; // a, b - счетчики в массивах
- int[] result = new int[len];
- for (int i = 0; i < len; i++) {
- if (b < len_2 && a < len_1) {
- if (arr_1[a] > arr_2[b])
- result[i] = arr_2[b++];
- else
- result[i] = arr_1[a++];
- } else if (b < len_2) {
- result[i] = arr_2[b++];
- } else {
- result[i] = arr_1[a++];
- }
- }
- return result;
- }
По скорости примерно одинаковые. Рекурсивная версия немного быстрее (по крайней мере на массивах длинной менее 100 000)