← Назад к статьям

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

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

Например, рассмотрим рекурсивную функцию, вычисляющую факториал числа, на языке Rust:

fn factorial(n: u64) -> u64 {
    match n {
        0 => 1,
        _ => n * factorial(n - 1),
    }
}

Эта версия функции не является хвостовой рекурсией, поскольку умножение выполняется после рекурсивного вызова.

Теперь давайте преобразуем её в хвостовую рекурсию:

fn factorial(n: u64) -> u64 {
    fn helper(n: u64, acc: u64) -> u64 {
        match n {
            0 => acc,
            _ => helper(n - 1, acc * n),
        }
    }
    helper(n, 1)
}

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

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

Важно отметить, что хвостовая рекурсия не ограничивается только языком Rust. Она широко применима и в других языках программирования, таких как Python, Java, JavaScript, PHP, C++ и др. Хвостовая рекурсия позволяет эффективно использовать системные ресурсы, что особенно важно при работе с большими объемами данных или при реализации сложных алгоритмов.