Сортировка чисел аргумента сортирован от краев самые большие в середине наименьшие

Рейтинг: 0Ответов: 2Опубликовано: 13.02.2023

Прошу помогите отсортировать от краев самые большие в середине наименьшие. Пример вводим - 8, 1, 2, 5, 7, 12, 3 получаем - 12, 7, 3, 1, 2, 5, 8 Голову ломаю не могу понять как это сделать. Язык программирование Java

Ответы

▲ 0

Похоже для решения такой задачи проще использовать дополнительную память для сортировки входного массива, который нужно затем перезаполнить по соответствующим индексам.

Вариант решения с использованием 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]
----
▲ 0

Я решу на 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