Які переваги рекурсії?
Деякі мови програмування можуть оптимізувати хвостову рекурсію, але, загалом кажучи, рекурсія споживає більше ресурсів, ніж звичайні петлі.
Чи можливо мати ітераційну версію якоїсь рекурсивної функції?
Які переваги рекурсії?
Деякі мови програмування можуть оптимізувати хвостову рекурсію, але, загалом кажучи, рекурсія споживає більше ресурсів, ніж звичайні петлі.
Чи можливо мати ітераційну версію якоїсь рекурсивної функції?
Відповіді:
Так, ви можете кодувати рекурсивні функції як ітерації. В основному це вимагає, щоб ви підтримували інформацію вручну, що інакше було б опікуватися методом виклику коду, згенерованого компілятором.
Іншими словами, вам потрібен стек, де кожен запис - це структура, що містить передані параметри та всі локальні змінні. Ви завжди працюєте над найпопулярнішим записом на стеці. Якщо вам потрібно зателефонувати собі, створіть новий запис і поставте зверху стек. Після завершення візьміть верхній запис стека, що відкриває нижченаведене, і використовуйте попередньо верхній запис для вилучення значень, що повертаються, та відповідно оновіть новий самий верхній запис.
Я пропоную вам вивчити компіляторну книгу, щоб побачити, як це зазвичай реалізується в машинному коді.
Рекурсія часто є більш природним способом погляду на речі, ніж ітерація. Наприклад, розглянемо внутрішнє обхід бінарного дерева: inorder(left); process(); inorder(right);
набагато простіше, ніж явно підтримувати стек.
Поки ви не заглиблюєтесь занадто глибоко (видуваючи стек), різниця у використанні ресурсів зазвичай тривіальна. Не турбуйтеся про це взагалі. Простий код зазвичай краще, ніж оптимізований рукою код, хоча є винятки. Правильно, як правило, краще, ніж швидко.
Будь-який рекурсивний алгоритм може бути виражений як ітеративний алгоритм, але вам може знадобитися зберігати явний стек (відповідний стеку викликів, який обробляється неявно). Зрештою, якщо ви компілюєте рекурсивну функцію, ви отримуєте щось, що залежить від маніпулювання стеком і циклічного перегляду функції, і це є ітераційним.
Хвосто-рекурсивні функції можна легко перевести в петлі, і їм не потрібен стек, але це особливий випадок.
Які переваги рекурсії?
Спробуйте вирішити проблему Тауер Ханой ітеративно. Після того, як ви відмовитесь, подивіться на ітераційне рішення та порівняйте його з рекурсивним. Який простіший?
Чи можливо мати ітераційну версію якоїсь рекурсивної функції?
Так, в принципі. Однак для багатьох проблем, включаючи дуже поширені завдання, такі як обхід дерева, рекурсивні рішення набагато простіші та елегантніші, ніж ітераційні.
Які переваги рекурсії?
Простота. Без оптимізації хвостових викликів, звичайно, потрібно більше ресурсів (стек), але як би ви реалізували, скажімо, deltree
на Java без рекурсії? Поворот полягає в тому, що вони delete()
можуть видаляти каталоги, лише якщо вони порожні; ось це з рекурсією:
deltree(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
for (File subFileOrDirectory : fileOrDirectory.listFiles()) {
deltree(subFileOrDirectory);
}
}
fileOrDirectory.delete();
}
Я вважаю, що рекурсія - це один із тих інструментів, якими повинен жити програміст. За допомогою рекурсії ви можете «продумати» свої алгоритми та вирішити їх так, як ви про це думали. Але, зауважу, усі говорять про те, наскільки хороша рекурсія і скільки простоти приносить код, щодо цього я маю сказати кілька речей:
Маючи це на увазі, вивчіть рекурсію! це смішно, складно, і це розгромить ваш мозок !, але ви виявите, що любите це.
Удачі!