Сортировка чисел аргумента сортирован от краев самые большие в середине наименьшие
Прошу помогите отсортировать от краев самые большие в середине наименьшие. Пример вводим - 8, 1, 2, 5, 7, 12, 3 получаем - 12, 7, 3, 1, 2, 5, 8 Голову ломаю не могу понять как это сделать. Язык программирование Java
Ответы (2 шт):
Автор решения: Nowhere Man
→ Ссылка
Похоже для решения такой задачи проще использовать дополнительную память для сортировки входного массива, который нужно затем перезаполнить по соответствующим индексам.
Вариант решения с использованием PriorityQueue и вычислением индексов:
- начальный индекс будет ровно середина массива для нечетной длины и меньше на 1 для четной длины массива
- затем для вычисления следующего индекса нужно будет брать знакопеременные приращения: 1, -2, 3, -4...
Реализация:
public static void spiralSort(int[] arr) {
PriorityQueue<Integer> q = new PriorityQueue<>(arr.length);
for (int n : arr) {
q.add(n);
}
for (int i = arr.length / 2 + arr.length % 2 - 1, d = 1, s = -1;
!q.isEmpty(); i += (s *= -1) * d++)
{
arr[i] = q.poll();
}
}
Тесты:
int[][] tests = {
{8, 1, 2, 5, 7, 12, 3},
{8, 1, 2, 5, 7, 12, 3, 11},
{1},
{3, 1}
};
for (int[] arr : tests) {
System.out.println("before: " + Arrays.toString(arr));
spiralSort(arr);
System.out.println("sorted: " + Arrays.toString(arr));
System.out.println("----");
}
Результаты:
before: [8, 1, 2, 5, 7, 12, 3]
sorted: [12, 7, 3, 1, 2, 5, 8]
----
before: [8, 1, 2, 5, 7, 12, 3, 11]
sorted: [11, 7, 3, 1, 2, 5, 8, 12]
----
before: [1]
sorted: [1]
----
before: [3, 1]
sorted: [1, 3]
----
Автор решения: tym32167
→ Ссылка
Я решу на C#, переведете на джаву сами. Чтобы сделать подобное прямо на месте, без доп памяти, нужно:
Определить метод для обмена переменными в массиве
private void swap(int[] data, int i, int j)
{
var tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
Потом сам алгоритм
var arr = new int[] { 12, 8, 7, 5, 3, 2, 1 };
// Сортируем массив по убыванию
Array.Sort(arr, Comparer<int>.Create((x, y) => y.CompareTo(x)));
// разделяем, четные слева, нечетные справа.
// По сути я иду по нечетным слева и меняю их на четные справа
var leftOdd = 0;
var rightEven = arr.Length - 1;
while (leftOdd < rightEven)
{
if (leftOdd % 2 == 0) leftOdd++;
if (rightEven % 2 != 0) rightEven--;
swap(arr, leftOdd, rightEven);
leftOdd += 2;
rightEven -= 2;
}
// Заново сортируем левую часть по убыванию
Array.Sort(arr, 0, arr.Length - arr.Length / 2, Comparer<int>.Create((x, y) => y.CompareTo(x)));
// А вот правую часть сортируем по возрастанию
Array.Sort(arr, arr.Length - arr.Length / 2, arr.Length / 2, Comparer<int>.Create((x, y) => x.CompareTo(y)));
// Выводим результат
Console.WriteLine(string.Join(" ", arr));
Вывод
12 7 3 1 2 5 8