Что может вас смущать, так это то, что рекурсивный вызов не происходит в конце функции, как в случае с вашим примером f()
. Это означает, что у вас есть код, который выполняется перед входом в код рекурсии и , который выполняется после выхода из рекурсии . Давайте посмотрим, что происходит в factorial
:
Рекурсивный шаг
Выберите любой рекурсивный шаг i
, который вам нравится, который не является базовым. А затем посмотрите, что делает функция, не выполняя рекурсию.
Для вашей функции factorial
давайте возьмем вызов factorial(i)
, где i
отличается от 0
. Этот призыв делает три вещи:
- print
2*i
пробелы и "factorial i"
- факториал вызова (i-1)
- печать
2*i
пробелы и "возвращение я"
Итак, результат будет:
(2*i spaces) factorial i
# everything factorial(i-1) outputs
(2*i spaces) returning i
Вы увидите, что вывод factorial(i-1)
зажат между выводами factorial(i)
. Чтобы выполнить рекурсию, все, что вам нужно сделать, это взорвать шаблон. Давайте сделаем еще один шаг i-1
во внимание:
(2*i spaces) factorial i
(2*(i-1) spaces) factorial i-1
# everything factorial(i-1) outputs
(2*(i-1) spaces) returning i-1
(2*i spaces) returning i
Итак, вы видите, что отступ уменьшается с вызовами, так как i
уменьшается, что составляет v-shape .
Базовый корпус
Он просто печатает
factorial 0
returning 1
Собираем все вместе
Теперь вы можете найти словесное выражение для того, что factorial(i)
делает:
factorial(i)
производит вывод v-формы
factorial i
factorial i-1
...
factorial 0
returning 1
...
returning i-1
returning i
Если это верно для случая i == 0
, заключите оттуда, что это верно для i+1
, если вы предполагаете, что это верно для i
, используя список в разделе рекурсивный шаг, Сделав это, вы можете быть уверены, что factorial(n)
работает для любого n >= 0
.