PassFront
  1. PassFront
  2. База знаний
  3. Рекурсия, жадные алгоритмы и ДП

Как рекурсия использует стек вызовов и чем опасна глубокая рекурсия?

Рекурсия, жадные алгоритмы и ДП

Каждый рекурсивный вызов кладёт на стек новый фрейм с локальными переменными и адресом возврата; при слишком глубокой рекурсии стек переполняется — stack overflow.

Что происходит при вызове

  • Фрейм хранит параметры, локальные переменные и точку возврата.
  • Потребление памяти — O(глубина): наивный факториал за n вызовов ест O(n) стека.

Как бороться с переполнением

  • Переписать итеративно с явным стеком на куче.
  • Хвостовая рекурсия: если вызов — последнее действие функции, некоторые языки переиспользуют фрейм (в Python её нет; в JS она есть в спецификации ES2015, но реализована только в Safari).
  • Увеличение лимита стека — костыль, а не решение.

Когда рекурсия оправдана

Задачи с естественной рекурсивной структурой: обход деревьев, divide and conquer, backtracking — итеративная версия вышла бы заметно сложнее и подверженнее ошибкам.

Коротко для собеседования

Каждый вызов занимает фрейм на стеке, так что рекурсия стоит O(глубины) памяти, а стек ограничен примерно мегабайтом на поток. Для глубоких структур переписывайте рекурсию на цикл с явным стеком — в Python хвостовой оптимизации нет, а в JS она работает только в Safari.

Другие вопросы раздела