Рекурсия
Рекурсия — это вызов функцией самой себя. На примере факториала и чисел Фибоначчи изучаем устройство рекурсии, условие остановки и подводные камни.
Список тем (3 из 11)
Глава 1. Алгоритмы
Глава 2. Структуры данных
Глава 3. Базы данных
Глава 4. Современные технологии и проекты
Рекурсия — это вызов функцией самой себя в ходе своей работы. Сложная задача сводится к такой же, но меньшей задаче, и так продолжается, пока не будет достигнут простейший случай. В любой правильной рекурсивной функции есть две части: условие остановки (простейший случай, ответ на который даётся без рекурсии) и рекурсивный шаг (функция вызывает себя с меньшими данными).
Классический пример — факториал: n! = n · (n − 1)!, 0! = 1. На Python это записывается так: def f(n): return 1 if n == 0 else n * f(n - 1). При вызове f(3) вычисляется 3 * f(2), затем 2 * f(1), затем 1 * f(0); дойдя до f(0), ответы возвращаются в обратном порядке, и получается 6. Без условия остановки функция вызывала бы себя бесконечно.
Числа Фибоначчи тоже определяются рекурсивно: fib(n) = fib(n - 1) + fib(n - 2), fib(0) = 0, fib(1) = 1. Но при простой записи одни и те же значения вычисляются много раз, и с ростом n время растёт очень быстро; например, fib(40) таким способом считается заметно долго. В таких случаях эффективнее запоминать промежуточные результаты или использовать цикл.
Каждый рекурсивный вызов занимает место в памяти, поэтому слишком глубокая рекурсия приводит к переполнению. В Python глубина ограничена (обычно примерно 1000 вызовов), и при превышении возникает ошибка RecursionError. Рекурсия удобна для древовидных данных и алгоритмов «разделяй и властвуй», а для простого повторения цикл часто быстрее и безопаснее.
Главное
- Рекурсия — вызов функцией самой себя с меньшими данными.
- В рекурсии обязательны условие остановки и рекурсивный шаг.
- Без условия остановки рекурсия не завершится и возникнет ошибка.
- Простая рекурсивная запись чисел Фибоначчи медленна, так как значения вычисляются повторно.
- Глубина рекурсии в Python ограничена (около 1000).
Практические задания
- Вычислите вручную факториал
f(4)по рекурсивной функции: запишите по порядку все вызовы и возвращаемые ими значения. - Напишите рекурсивную функцию, возвращающую сумму чисел от
nдо1. Сравните результат с вариантом на цикле. - С помощью рекурсивной функции найдите сумму цифр числа (например, для 2745 это 18). Подсказка:
n % 10— последняя цифра,n // 10— остальная часть.
Вопросы для закрепления
Проверьте себя: сначала подумайте, потом откройте ответ.
1Какие две обязательные части есть у рекурсивной функции?Показать ответСкрыть ответ
Условие остановки (простейший случай) и рекурсивный шаг (вызов функцией себя с меньшими данными).2Почему рекурсивный `fib(40)` работает медленно?Показать ответСкрыть ответ
Одни и те же значения пересчитываются бесчисленное число раз, а число вызовов очень быстро растёт с ростом n.3К какой ошибке приводит слишком глубокая рекурсия в Python?Показать ответСкрыть ответ
`RecursionError`: глубина вызовов превышает ограничение (обычно около 1000).
Войдите на сайт
Слайды и PDF доступны только зарегистрированным пользователям: и просмотр, и скачивание. Вход бесплатный.
Войдите на сайт
Слайды и PDF доступны только зарегистрированным пользователям: и просмотр, и скачивание. Вход бесплатный.
Пройдено тем: 0 из 11
Войти и отметить