У меня есть метод сортировки рекурсивного выбора с начальным рекурсивным вызовом в другом методе. Но я использовал цикл for в рекурсивном методе. Это все еще рекурсивный метод, если у меня есть цикл for? Как реализовать рекурсивную сортировку выбора без цикла for?

private static void SelectionSortRecursive(int[] Array, int n) // sorted in descending order recursively
{
    if (n >= Array.Length - 1)
        return;
    int max = n;
    for (int i = n + 1; i < Array.Length; i++)
    {
        if (Array[i] > Array[max])
            max = i;
    }

    swap(Array, n, max);
    SelectionSortRecursive(Array, n + 1);
}

Алгоритм сортировки работает и сортирует правильно.

2
Kelly Kolesky 2 Май 2019 в 14:49

3 ответа

Лучший ответ

Оставить свой цикл for в ... все еще рекурсивным, потому что у вас уже есть рекурсивный вызов, и добавление любого количества нерекурсии с рекурсией все еще оставляет рекурсию.

Реализация вышеупомянутого без цикла for ... это можно сделать. @ Ответ Emaro верен в том смысле, что в нем нет явного цикла for в коде, но используемый им LINQ по-прежнему является неявной конечной нерекурсивной итерацией по массиву ... то есть циклом.

Так что если вы действительно не хотите цикл, вы можете заменить этот на рекурсию.

private static void SelectionSortRecursive(int[] arr, int n)
{
    if (n >= arr.Length - 1)
        return;

    int max = n;
    Max(n + 1);

    swap(arr, n, max);
    SelectionSortRecursive(arr, n + 1);

    void Max(int i)
    {
        if (i == arr.Length)
            return;
        if (arr[i] > arr[max])
            max = i;
        Max(i + 1);
    }
}

Это странное решение, не то, которое я бы написал лично, но, тем не менее, вы идете.

1
Kit 2 Май 2019 в 12:29

Используйте метод linq Max (), чтобы выбрать наибольшее целое число. С помощью Skip () мы пропускаем уже отсортированные элементы при запросе максимального значения. Нет цикла с этим кодом.

private static void SelectionSortRecursive(int[] Array, int n)
{
    if (n >= Array.Length - 1)
        return;

    var max = System.Array.IndexOf(Array, Array.Skip(n).Max());
    swap(Array, n, max);

    SelectionSortRecursive(Array, n + 1);
}

Если код не работает таким образом, обязательно добавьте using System.Linq; вверху файла.

< Сильный > Edit
Исправьте indexOf и пропустите значение.

Вам нужно набрать System.Array, поскольку локальная переменная также называется Array. Местные вариации должны быть в нижнем верблюжьем корпусе. Образец:

private static void SelectionSortRecursive(int[] array, int n)
{
    if (n >= array.Length - 1)
        return;

    var max = Array.IndexOf(array, array.Skip(n).Max());
    swap(array, n, max);

    SelectionSortRecursive(array, n + 1);
}
0
Emaro 2 Май 2019 в 12:19

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

Что-то вроде этого:

private static void SelectionSortRecursive(int[] Array, int n) // sorted in descending order recursively
{
    if (n >= Array.Length - 1)
        return;
    int max = n;

    max = Compare(Array, max, n+1);
    swap(Array, n, max);
    SelectionSortRecursive(Array, n + 1);
}

private static int Compare(int[] arr, int max, int i)
{
    if(i == arr.Length)
        return max;

    if (arr[i] > arr[max])
        max = i;
    max = Compare(arr,max,++i);
    return max;
}
0
akg179 2 Май 2019 в 13:10