Что такое рекурсия? Приведи пример.

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Средний
#JavaScript #Функции #База JS

Краткий ответ

Рекурсия — это когда функция вызывает саму себя. Так можно решать задачи, которые повторяются на каждом шагу, но становятся проще. Классический пример — вычисление факториала числа. 🔁

Функция, которая вызывает саму себя:

function countDown(n) {
  if (n <= 0) return;
  console.log(n);
  countDown(n - 1); // Вызов самой себя
}

Полный ответ

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

Что такое рекурсия

Функция, которая вызывает саму себя:

function countDown(n) {
  if (n <= 0) return;
  console.log(n);
  countDown(n - 1); // Вызов самой себя
}

Как работает рекурсия

Базовый случай

function factorial(n) {
  // Базовый случай — остановка рекурсии
  if (n <= 1) return 1;
  
  // Рекурсивный случай
  return n * factorial(n - 1);
}

Стек вызовов

// factorial(3) создаёт стек:
// factorial(3) → 3 * factorial(2)
// factorial(2) → 2 * factorial(1)
// factorial(1) → 1 (базовый случай)

Простые примеры

Вычисление степени

function power(base, exponent) {
  if (exponent === 0) return 1;
  return base * power(base, exponent - 1);
}
 
console.log(power(2, 3)); // 8 ✅

Обход вложенных структур

const tree = {
  value: 1,
  children: [
    { value: 2, children: [] },
    { value: 3, children: [{ value: 4, children: [] }] }
  ]
};
 
function sumTree(node) {
  let sum = node.value;
  for (let child of node.children) {
    sum += sumTree(child); // Рекурсивный вызов
  }
  return sum;
}

Важные особенности

1. Базовый случай

function recursive(n) {
  // ❌ Без базового случая — бесконечная рекурсия
  // return recursive(n); // Stack overflow!
  
  // ✅ С базовым случаем
  if (n <= 0) return; // Остановка
  return recursive(n - 1);
}

2. Память

// Каждый вызов занимает место в стеке
// Слишком много вызовов — ошибка переполнения стека

Где используется рекурсия

Работа с деревьями

// Обход папок и файлов
function scanDirectory(dir) {
  console.log(dir.name);
  for (let item of dir.children) {
    if (item.isDirectory) {
      scanDirectory(item); // Рекурсивный обход
    }
  }
}

Алгоритмы

// Быстрая сортировка
function quickSort(arr) {
  if (arr.length <= 1) return arr;
  
  const pivot = arr[0];
  const less = arr.slice(1).filter(x => x <= pivot);
  const greater = arr.slice(1).filter(x => x > pivot);
  
  return [...quickSort(less), pivot, ...quickSort(greater)];
}

Частые ошибки

1. Отсутствие базового случая

// ❌ Бесконечная рекурсия
function bad(n) {
  return bad(n - 1); // Нет остановки!
}
 
// ✅ С остановкой
function good(n) {
  if (n <= 0) return; // Базовый случай
  return good(n - 1);
}

2. Слишком глубокая рекурсия

// ❌ Может вызвать переполнение стека
function deep(n) {
  if (n <= 0) return;
  return deep(n - 1);
}
 
// deep(100000); // Ошибка!
 
// ✅ Итерация вместо глубокой рекурсии
function iterative(n) {
  for (let i = n; i > 0; i--) {
    // То же самое, но без рекурсии
  }
}

Простые правила

  1. Базовый случай — всегда нужна остановка 🔚
  2. Упрощение — каждый вызов должен приближать к базовому случаю 📉
  3. Память — рекурсия использует стек вызовов 🧠
  4. Деревья — идеальна для работы с иерархическими структурами 🌳
  5. Простота — иногда проще, чем циклы 🔄

Рекурсия — это элегантный способ решения задач, которые повторяются на разных уровнях. Но нужно быть осторожным с базовым случаем! ⚠️


Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪