Хвостовая рекурсия

Хвостовая рекурсия

Случай рекурсии, когда рекурсивный вызов функции происходит в конце её работы. Это используется в функциональных языках для оптимизации, так как такие функции легко преобразуются в итеративные алгоритмы, явное задание которых не предусмотрено декларативными языками.

Пример на Scheme:

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

Другими словами, рекурсия — способ общего определения объекта или действия через себя, с использованием ранее заданных частных определений. Рекурсия используется, когда можно выделить самоподобие задачи.

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

Содержание

  • Метод Гаусса — Жордана для решения Системы линейных алгебраических уравнений является рекурсивным.
  • Факториал целого неотрицательного числа n обозначается n! и определяется как n!=n*(n-1) при n > 0 и n! = 1 при n = 0
  • Числа Фибоначчи определяются с помощью рекуррентного соотношения: Первое и второе числа Фибоначчи равны 1 Для n > 2 , n ? e число Фибоначчи равно сумме (n ? 1) -го и (n ? 2) -го чисел Фибоначчи
  • Практически все геометрические фракталы задаются в форме бесконечной рекурсии. (например, треугольник Серпинского).
  • Задача «Ханойские башни». Её содержательная постановка такова: В одном из буддийских монастырей монахи уже тысячу лет занимаются перекладыванием колец. Они располагают тремя пирамидами, на которых надеты кольца разных размеров. В начальном состоянии 64 кольца были надеты на первую пирамиду и упорядочены по размеру. Монахи должны переложить все кольца с первой пирамиды на вторую, выполняя единственное условие — кольцо нельзя положить на кольцо меньшего размера. При перекладывании можно использовать все три пирамиды. Монахи перекладывают одно кольцо за одну секунду. Как только они закончат свою работу, наступит конец света. Рекурсивный вариант решения задачи можно описать так:

Алгоритм по передвижению башни, алгоритм передвинет нужное количество дисков из пирамиды «источник» на пирамиду «задание» используя «запасную» пирамиду.

Если число дисков равно одному, тогда:

  • Передвиньте диск из источника в задание

В противном случае:

  • Рекурсивно передвиньте все диски кроме одного из источника в запас, используя задание как запас
  • Передвиньте оставшийся диск из источника в задание
  • Передвиньте все диски из запаса в задание используя источник как запас

Рекурсия в программировании

В программировании рекурсия — вызов функции (процедуры) из неё же самой, непосредственно (простая рекурсия) или через другие функции (сложная рекурсия), например, функция A вызывает функцию B , а функция B — функцию A . Количество вложенных вызовов функции или процедуры называется глубиной рекурсии.

Мощь рекурсивного определения объекта в том, что такое конечное определение способно описывать бесконечно большое число объектов. С помощью рекурсивной программы же возможно описать бесконечное вычисление, причём без явных повторений частей программы.

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

Впрочем, имеется специальный тип рекурсии, называемый «хвостовой рекурсией». Интерпретаторы и компиляторы функциональных языков программирования, поддерживающие оптимизацию кода (исходного и/или исполняемого), автоматически преобразуют хвостовую рекурсию к итерации, благодаря чему обеспечивают выполнение алгоритмов с хвостовой рекурсией в ограниченном объёме памяти. Такие рекурсивные вычисления, даже если они формально бесконечны (например, когда с помощью рекурсии организуется работа командного интерпретатора, принимающего команды пользователя), никогда не приводят к исчерпанию памяти. К сожалению, далеко не всег

*Предлагаемые к заключению договоры или финансовые инструменты являются высокорискованными и могут привести к потере внесенных денежных средств в полном объеме. До совершения сделок следует ознакомиться с рисками, с которыми они связаны.

Ссылка на основную публикацию