Автор оригинала: Yazeed Bzadough.
Функция называет себя, пока кто-то не остановится.
Рекурсия может чувствовать себя трудно для новых разработчиков. Возможно, это потому, что многие ресурсы учат его использовать алгоритмические примеры (фибоначчи, связанные списки). Этот кусок надеется в представлении вещей прямо, используя один простой пример.
Основная идея
Рекурсия когда функция звонит себе, пока кто-то не остановится. Если никто не останавливает это, то это … Рекурсировать (позвонить себе) навсегда.
Рекурсивные функции позволяют выполнить единицу работы несколько раз. Это именно то, что для/пока Петли давайте добились! Иногда, однако, рекурсивные решения являются более элегантным подходом к решению проблемы.
Функция обратного отсчета
Давайте создадим функцию, которая подсчитывается с данного номера. Мы будем использовать это так.
countDownFrom(5); // 5 // 4 // 3 // 2 // 1
И вот наш алгоритм решить эту проблему.
- Возьмите один параметр под названием
НомерОтказ Это наша отправная точка. - Перейти из
Номердо0, регистрацию каждого по пути.
Начнем с для Цикл подход, а затем сравнивать его с рекурсивным.
Императивный подход (петли)
function countDownFrom(number) {
for (let i = number; i > 0; i--) {
console.log(i);
}
}
countDownFrom(5);
// 5
// 4
// 3
// 2
// 1
Этот содержит обе алгоритмические шаги.
- ✅ Возьмите один параметр под названием
НомерОтказ - ✅ Войти все от
Номерк0Отказ
Рекурсивный подход
function countDownFrom(number) {
if (number === 0) {
return;
}
console.log(number);
countDownFrom(number - 1);
}
countDownFrom(5);
// 5
// 4
// 3
// 2
// 1
Этот также проходит.
- ✅ Возьмите один параметр под названием
НомерОтказ - ✅ Войти все от
Номерк0Отказ
Таким образом, концептуально два подхода одинаковы. Тем не менее, они получают работу по-разному.
Отладка нашего императивного решения
Для более визуального примера давайте поставить Отладчик В нашей версии петли и бросьте его в инструменты разработчика Chrome.
function countDownFrom(number) {
for (let i = number; i > 0; i--) {
console.log(i);
debugger;
}
}
Посмотрите, как он использует дополнительную переменную, Я , чтобы отслеживать текущий номер? Как вы итерации Я уменьшается, в конечном итоге ударяет 0 и прекращается.
И в для Цикл мы указали «Стоп, если I> 0 ».
Отладка нашего рекурсивного решения
function countDownFrom(number) {
if (number === 0) {
return;
}
console.log(number);
debugger;
countDownFrom(number - 1);
}
Рекурсивная версия не нужна дополнительных переменных для отслеживания его прогресса. Обратите внимание, как куча функций ( стека вызовов ) растет, как мы рекурсим?
Это потому, что каждый звонок на CountDownRom добавляет в стек, кормить его Номер - 1 Отказ Делая это, мы проходим вдоль обновленного Номер каждый раз. Никакого дополнительного состояния не нужно!
Это главное различие между двумя подходами.
- Итеративное использование внутреннего состояния (дополнительные переменные для подсчета и т. Д.).
- Рекурсивное не делает, это просто передает обновленные параметры между каждым вызовом.
Но как либо версия знает, когда остановиться?
Бесконечные петли
В ваших путешествиях вы, возможно, были предупреждены о страшной бесконечной петле.
? THIS RUNS FOREVER, BE WARNED ?
while (true) { console.log('WHY DID YOU RUN THIS?!' }
? THIS RUNS FOREVER, BE WARNED ?
for (i = 0;;) { console.log('WHY DID YOU RUN THIS?!') }
Поскольку они теоретически управляют навсегда, бесконечный цикл остановят вашу программу и, возможно, выровнете ваш браузер. Вы можете помешать им всегда кодировать Остановка условия Отказ
✅ This does not run forever
x = 0;
while (x < 3) { console.log(x); x++; }
✅ This does not run forever
for (x = 0; x < 3; x++) { console.log(x); }
В обоих случаях мы регистрируем х , увеличивайте его и остановитесь, когда это становится 3 Отказ Наше CountDownRom Функция имела подобную логику.
// Stop at 0 for (let i = number; i > 0; i--)
Опять же, петли нужны дополнительное состояние, чтобы определить, когда они должны остановиться. Вот что х и Я для.
Бесконечная рекурсия
Рекурсия также представляет такую же опасность. Не упорно написать функцию самоссылки, которая перехватит ваш браузер.
?THIS RUNS FOREVER, BE WARNED?
function run() {
console.log('running');
run();
}
run();
// running
// running
// ...
Без остановки, Беги навсегда позвони себе. Вы можете исправить это с Если утверждение.
✅ This does not run forever
function run(x) {
if (x === 3) return;
console.log('running');
run(x + 1);
}
run(0);
// running
// running
// running
// x is 3 now, we're done.
Базовый вариант
Это известно как Базовый чехол – Наши рекурсивные CountDownRom. был один.
if (number === 0) {
return;
}
Это та же идея, что и логика остановки нашей петли. Какой бы подход вы выбираете, всегда помните, что в какой-то момент Это должно быть остановлено .
Резюме
- Рекурсия – это когда функция называет себя, пока кто-то не остановится.
- Его можно использовать вместо петли.
- Если никто не останавливает его, он будет пройден навсегда и схватить вашу программу.
- А Базовый чехол это условие, которое останавливает рекурсию. Не забудьте их добавить!
- Петли используют дополнительные переменные состояния для отслеживания и подсчета, а рекурсия использует только прилагаемые параметры.
Спасибо за прочтение
Для большего количества контента посмотрите https://yazeedb.com Отказ И, пожалуйста, дайте мне знать, что еще вы хотели бы увидеть! Мои DMS открыты в Twitter.
До скорого!
Оригинал: “https://www.freecodecamp.org/news/quick-intro-to-recursion/”