Немного о рекурсии

Статья написана студентом Хекслета. Мнение автора может не совпадать с позицией редакции
Читать в полной версии →

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

Хотелось бы добавить к этой теме немного от себя. Допустим, вот пример самодельной экспериментальной рекурсивной функции, которая определяет — является ли число простым? Она принимает два параметра: проверяемое число (number) и делитель (devider), но сразу предупрежу, что делителем обязательно является число, которое на единицу меньше проверяемого (devider === number - 1):

const isPrime = (number, devider) => {
  if (number <= 0) return false;
  if (devider === 1) return true;
  if (number % devider === 0) return false;
  return isPrime(number, devider - 1);
};

console.log(isPrime(47, 46)); // true

Как вам, наверное, уже известно, для корректного завершения работы рекурсивной функции необходимо наличие базового случая. В вышеприведенной функции им является (devider === 1). Но хотелось бы обратить внимание на последнюю строку с return: мы видим там работу «движка» рекурсии, где функция вызывает саму себя и «топливом» для этой работы является уменьшение параметра devider (на единицу с каждым вызовом). Это чем-то похоже на работу классического цикла for (let i = 0; i < arr.length; i += 1) { ... }, топливом для работы которого является изменение переменной i. При достижении базового случая — все, стоп-машина, топливо devider почти исчерпано (примерно такая вот аналогия). Дополнительно также можно рассмотреть алгоритм Евклида (с рекурсией) для вычисления наибольшего общего делителя для двух целых чисел:

const gcd = (a, b) => b === 0 ? Math.abs(a) : gcd(b, a % b); // ECMAScript версий ≥ 6.0

Признаться честно, ее логика и сейчас сложна лично для моего понимания. Чтобы так ловко сконструировать, необходимы глубокие познания в JavaScript, но даже и так заметно, что в выражении (соответствующем false) работает «движок» рекурсии, который остановится при вычислении наибольшего общего делителя (базовый случай) в выражении тернарного оператора, соответствующего true.

В общем, примерно как-то так :)

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