Шаг 97.
Рекурсия на Python.
Множественная рекурсия I: "разделяй и властвуй". Отсортирован ли список?

    На этом шаге мы рассмотрим рекурсивное решение этой задачи.

    В этой задаче сортировки (скажем, по возрастанию) входом является список a из n элементов, которые можно отсортировать операцией (или некоторой функцией, позволяющей сравнивать элементы, реализуя полное бинарное отношение следования), а выходом - логическое значение, которое можно выразить как

   n-2            
    (ai ≤ ai+1) .       (6.1)
   i=0            

    Таким образом, результат равен True, если элементы списка располагаются (не строго) в возрастающем или неубывающем порядке.

    Размер этой задачи - количество элементов списка. Если список содержит один элемент, то результат - очевидно, True. Кроме того, можно считать, что пустой список тоже упорядочен.

    Задачу можно решить линейно-рекурсивным методом, который на этапе декомпозиции уменьшает размер задачи на 1. Однако мы представим решение, которое делит входной список задачи пополам и приводит её к следующей декомпозиции:

    f(a) = (а0 ≤ а1) ∧ ... ∧ (а⌊n/2⌋-2 ≤ а⌊n/2⌋-1)  {подзадача 1}
           ∧
           (а⌊n/2⌋-1 ≤ а⌊n/2⌋) ∧ (а⌊n/2⌋ ≤ а⌊n/2⌋+1) ∧ ... ∧ (аn-2 ≤ аn-1) {подзадача 2}

    Очевидно, если весь список отсортирован по возрастанию, то обе его половины тоже должны быть отсортированы по возрастанию. Таким образом, метод может вызвать себя дважды с двумя соответствующими подсписками и выполнить логическую операцию И с их результатами. Наконец, объединение результатов подзадач требует дополнительного шага. В частности, последний элемент первого подсписка а⌊n/2⌋-1 должен быть не больше первого элемента второго подсписка а⌊n/2⌋. Это условие также требует ещё одной операции И в рекурсивном условии. В примере 6.1 приведена возможная реализация метода, который работает за время Ο(n), поскольку его стоимость вычисления:

            1,           если n ≤ 1
    T(n) = 
            2T(n/2) + 1, если n > 1

Пример 6.1. Функция, определяющая, отсортирован ли список по возрастанию
1
2
3
4
5
6
7
8
def is_list_sorted(a):
    n = len(a)
    if n <= 1:
        return True
    else:
        return (is_list_sorted(a[0:n // 2]) and    
                a[n // 2 - 1] <= a[n // 2] and    
                is_list_sorted(a[n // 2:n]))
Архив с файлом можно взять здесь.

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




Предыдущий шаг Содержание Следующий шаг