Рубрики
Без рубрики

Проверьте мое визуальное руководство по рекурсии (потому что картина стоит 1000 слов)

Автор оригинала: Jerry Muzsik.

В этой статье я объясню рекурсию (почти) полностью с визуальными представлениями. Я покажу, вместо объяснения, как каждый вызов рекурсивной функции взаимодействует со в целом начальной вызова функции – другими словами, как каждая часть соединяется с целым.

Несколько деталей:

  • Код написан в Python
  • Синие коробки представляют текущий объем функции
  • Подключение строки – это то, что возвращает функция

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

Мы посмотрим на три проблемы: найти анаграммы строки, сортировки слияния и башни Ханой. Они постепенно получают немного более нюансированные, поэтому следите за!

Я буду обсуждать более подробную информацию о рекурсии ниже.

Анаграммы

def anagrams(s):
    if s == "":
        return [s]
    else :
        ans = []
    for w in anagrams(s[1: ]):
        for pos in range(len(w) + 1):
            ans.append(w[: pos] + s[0] + w[pos: ])
    return ans

anagrams("abc")

# returns ['abc', 'bac', 'bca', 'acb', 'cab', 'cba']

Выше – это хорошее введение в стек вызова. Обратите внимание, как каждый предыдущий вызов ожидает возвращаемого значения рекурсивного вызова.

Также обратите внимание, как переменная АНС Значения все добавлены во время начального вызова функции (1).

Сортировка слиянием

def merge(lst1, lst2, lst3):
    i1, i2, i3 = 0, 0, 0
    n1, n2 = len(lst1), len(lst2)
    while i1 < n1 and i2 < n2:
        if lst1[i1] < lst2[i2]:
            lst3[i3] = lst1[i1]
            i1 = i1 + 1
        else:
            lst3[i3] = lst2[i2]
            i2 = i2 + 1
        i3 = i3 + 1
    
    # unequal length of lists? Check both
    while i1 < n1: 
        lst3[i3] = lst1[i1]
        i1 = i1 + 1
        i3 = i3 + 1
    
    while i2 < n2:
        lst3[i3] = lst2[i2]
        i2 = i2 + 1
        i3 = i3 + 1

def mergeSort(nums):
    n = len(nums)
    if n > 1:
        m = n // 2
        nums1, nums2 = nums[:m], nums[m:]
        mergeSort(nums1)
        mergeSort(nums2)
        merge(nums1, nums2,nums)
    
numbers = [7, 4, 6, 2, 8]
mergeSort(numbers)

print(numbers)
# returns sorted numbers (function altered underlying data structure)

Опять же, обратите внимание на порядок, в котором каждый звонок работает. Чтобы понять, как слияние работает, посмотрите на него. У вас в основном есть три указателя и две сортированные половины начального списка, которые постоянно сравниваются. Самое низкое число во время этого сравнения устанавливается на индекс, который указывает на начальный список (начиная с индекса 0).

Несколько заметок, если вы не привыкли к Python. Когда функция ничего не возвращает, он возвращает значение Нет Отказ Вы можете увидеть частое возвратное значение Нет На моих диаграммах, так как нет явных возвратных заявлений в МЕРГОРТ Отказ

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

Башня Ханой

Вот быстрый рассказ как сбоку, я обнаружил, что это было довольно поэтическим вступлением в башню Ханой:

def moveTower(n, source, dest, temp):
    if n == 1:
        print("Move disk from", source, "to", dest+".")
    else:
        moveTower(n-1, source, temp, dest)
        moveTower(1, source, dest, temp)
        moveTower(n-1, temp, dest, source)
    
 def hanoi(n):
    moveTower(n, "A", "C", "B")

Перемещение блоков основано на Математический принцип Отказ

От Статья Википедии :

  1. Переместить м – 1 дисков из Источник к Temp колышка Это оставляет диск м в качестве верхнего диска на исходном PEG.
  2. Переместить диск м от Источник к dest колышка
  3. Переместить м – 1 диски, которые мы только что поместили на запас из Temp к dest PEG, поэтому они размещены на вершине диска м не нарушая правила.

Но как это имеет смысл этого принципа? Ну, проверьте это.

Обратите внимание: повторяются три правила (черный текст), за исключением случаев, когда работает правило 2 (синий текст), поскольку алгоритм не достигает своего базового случая.

Слово на рекурсии

Эта статья является первым шагом в состоянии решить рекурсивные проблемы. Я создал это, чтобы помочь читателям понять, как работает рекурсион, и какова это реальность. Для каждой проблемы обратите внимание, как заказал каждую вызов функции и возвращаемое значение. Это так же, как компьютер читает код.

Основная базовая концепция рекурсии является это:

Функция, в которой был вызван рекурсивный вызов функции, должен дождаться дождаться рекурсивного вызова функции для завершения до того, как оно продолжит свой процесс.

Поэтому, если рекурсивная функция вызывает более рекурсивные функции, то он также должен ждать, пока эти рекурсивные функции возвращаются. Рекурсия, как правило, только включает функции, ожидающие функции, которые они призвали, чтобы вернуть что-то до продолжения.

Если вы хотите расти в царстве рекурсивных решений проблем, то вы должны изучать математику. Они одно и то же самое. Но идущий по математике находится за пределами объема этой статьи. Это Статья Википедии это хороший грунтовтер, чтобы начать с.

Ничего не поделаешь. Я должен поблагодарить, абсолютно и полностью, Структуры и алгоритмы данных с использованием Python и C ++ Давидом М. Рид, а также Джон Зелле, поскольку именно здесь была добыта эта замечательная цитата и алгоритмы.

И вот хороший вид на пространство, потому что, ну, рекурсия чувствует себя немного похоже на это.