Я знаю общую концепцию рекурсии. Я наткнулся на концепцию хвостовой рекурсии при изучении алгоритма быстрой сортировки. В этом видео о алгоритме быстрой сортировки из MIT в 18:30 секунд профессор говорит, что это хвостовой рекурсивный алгоритм. Мне не ясно, что на самом деле означает хвостовая рекурсия.
Может ли кто-нибудь объяснить концепцию на соответствующем примере?
Некоторые ответы, предоставленные SO-сообществом здесь .
algorithms
reference-request
recursion
Компьютерщик
источник
источник
Ответы:
Хвостовая рекурсия - это особый случай рекурсии, когда вызывающая функция больше не выполняет вычисления после выполнения рекурсивного вызова. Например, функция
является хвостовой рекурсивной (поскольку последняя инструкция является рекурсивным вызовом), тогда как эта функция не является хвостовой рекурсивной:
так как он выполняет некоторые вычисления после возврата рекурсивного вызова.
Хвостовая рекурсия важна, потому что она может быть реализована более эффективно, чем общая рекурсия. Когда мы делаем нормальный рекурсивный вызов, мы должны поместить адрес возврата в стек вызовов, а затем перейти к вызываемой функции. Это означает, что нам нужен стек вызовов, размер которого является линейным по глубине рекурсивных вызовов. Когда у нас есть хвостовая рекурсия, мы знаем, что как только мы вернемся из рекурсивного вызова, мы также сразу же вернемся, поэтому мы можем пропустить всю цепочку рекурсивных функций, возвращающихся и возвращающихся прямо к исходному вызывающему. Это означает, что нам не нужен стек вызовов для всех рекурсивных вызовов, и мы можем реализовать последний вызов как простой переход, который экономит нам пространство.
источник
def recurse(x): if x < 0 return 1; for i in range 100{ (do calculations) recurse(x)}
Проще говоря, хвостовая рекурсия - это рекурсия, в которой компилятор может заменить рекурсивный вызов командой "goto", поэтому скомпилированная версия не должна будет увеличивать глубину стека.
Иногда разработка хвостовой рекурсивной функции требует создания вспомогательной функции с дополнительными параметрами.
Например, это не хвостовая рекурсивная функция:
Но это хвосто-рекурсивная функция:
потому что компилятор может переписать рекурсивную функцию в нерекурсивную, используя что-то вроде этого (псевдокод):
Правило для компилятора очень простое: когда вы найдете "
return thisfunction(newparameters);
", замените его на "parameters = newparameters; goto start;
". Но это может быть сделано только в том случае, если значение, возвращаемое рекурсивным вызовом, возвращается напрямую.Если все рекурсивные вызовы в функции можно заменить таким образом, то это хвостовая рекурсивная функция.
источник
Мой ответ основан на объяснении, приведенном в книге « Структура и интерпретация компьютерных программ» . Я очень рекомендую эту книгу ученым.
Подход A: Линейный рекурсивный процесс
Форма процесса для подхода A выглядит следующим образом:
Подход B: Линейный итерационный процесс
Форма процесса для подхода B выглядит следующим образом:
Линейный итеративный процесс (подход B) выполняется в постоянном пространстве, хотя процесс является рекурсивной процедурой. Следует также отметить, что в этом подходе набор переменных определяет состояние процесса в любой точке, а именно.
{product, counter, max-count}
, Это также методика, с помощью которой хвостовая рекурсия позволяет оптимизировать компилятор.В подходе А есть больше скрытой информации, которую поддерживает интерпретатор, которая в основном представляет собой цепочку отложенных операций.
источник
Хвостовая рекурсия - это форма рекурсии, в которой рекурсивные вызовы являются последними инструкциями в функции (отсюда и хвостовая часть). Более того, рекурсивный вызов не должен состоять из ссылок на ячейки памяти, хранящие предыдущие значения (ссылки, отличные от параметров функции). Таким образом, мы не заботимся о предыдущих значениях, и для всех рекурсивных вызовов достаточно одного стекового кадра; хвостовая рекурсия является одним из способов оптимизации рекурсивных алгоритмов. Другое преимущество / оптимизация заключается в том, что существует простой способ преобразования хвостово-рекурсивного алгоритма в эквивалентный, который использует итерацию вместо рекурсии. Так что да, алгоритм быстрой сортировки действительно хвостовой рекурсии.
Вот итерационная версия:
источник