آموزش رایگان جاوا اسکریپت (JavaScript)

آموزش جامع توابع بازگشتی (Recursion) و کاربردهای آن در جاوا اسکریپت: مثال‌ها و مفاهیم

1403/07/29 20:15 محراب حسن زاده
آموزش جامع توابع بازگشتی (Recursion) و کاربردهای آن در جاوا اسکریپت: مثال‌ها و مفاهیم

توابع بازگشتی یکی از مفاهیم کلیدی در برنامه‌نویسی هستند که به شما این امکان را می‌دهند که مشکلات پیچیده را با استفاده از حل مسائل مشابه به شکل کوچکتر حل کنید. این تکنیک به ویژه در حل مسائل با ساختار درختی یا تکراری بسیار مفید است. در این مقاله، به بررسی مفهوم توابع بازگشتی، نحوه پیاده‌سازی آن‌ها در جاوا اسکریپت و کاربردهای متداول آن خواهیم پرداخت.

 

مفهوم توابع بازگشتی

تابع بازگشتی (Recursive Function) تابعی است که خود را درون بدنه خود فراخوانی می‌کند. این تکنیک به شما این امکان را می‌دهد که یک مسئله بزرگ را به مسائل کوچکتر مشابه تقسیم کنید و هر کدام را به صورت مستقل حل کنید.

 

ساختار تابع بازگشتی

یک تابع بازگشتی معمولاً شامل دو بخش اصلی است:

  • پایه (Base Case): شرایطی که باعث پایان یافتن فراخوانی‌های بازگشتی می‌شود.

  • گام بازگشتی (Recursive Case): شرایطی که تابع را به صورت بازگشتی فراخوانی می‌کند.

 

مثال ساده: محاسبه فاکتوریل

محاسبه فاکتوریل یک عدد مثال کلاسیکی از استفاده از توابع بازگشتی است:


function factorial(n) {
  // پایه: فاکتوریل 0 و 1 برابر با 1 است
  if (n === 0 || n === 1) {
    return 1;
  }
  // گام بازگشتی: n * فاکتوریل (n-1)
  return n * factorial(n - 1);
}

console.log(factorial(5)); // Output: 120

 

در این مثال:

  • پایه: اگر n برابر با 0 یا 1 باشد، فاکتوریل آن برابر با 1 است.

  • گام بازگشتی: برای محاسبه فاکتوریل n, تابع factorial(n-1) به صورت بازگشتی فراخوانی می‌شود.

 

کاربردهای توابع بازگشتی

توابع بازگشتی در حل مسائل پیچیده و مسائل ساختاریافته بسیار مفید هستند. در زیر به برخی از کاربردهای متداول آن‌ها اشاره خواهیم کرد:

 

جستجوی عمق‌اول (Depth-First Search)

در ساختارهای داده‌ای مانند درخت‌ها و گراف‌ها، الگوریتم‌های جستجوی عمق‌اول معمولاً با استفاده از توابع بازگشتی پیاده‌سازی می‌شوند.

مثال: جستجو در درخت باینری


class Node {
  constructor(value, left = null, right = null) {
    this.value = value;
    this.left = left;
    this.right = right;
  }
}

function depthFirstSearch(node, target) {
  if (node === null) return false;
  if (node.value === target) return true;
  return depthFirstSearch(node.left, target) || depthFirstSearch(node.right, target);
}

// ساخت درخت نمونه
const tree = new Node(1,
                new Node(2,
                  new Node(4),
                  new Node(5)),
                new Node(3));

console.log(depthFirstSearch(tree, 5)); // Output: true
console.log(depthFirstSearch(tree, 6)); // Output: false

 

در این مثال:

  • پایه: اگر node برابر با null باشد، جستجو به پایان می‌رسد.

  • گام بازگشتی: برای جستجوی در زیر درخت چپ و راست به صورت بازگشتی ادامه می‌دهیم.

 

مرتب‌سازی با استفاده از الگوریتم‌های بازگشتی

الگوریتم‌های مرتب‌سازی مانند Quick Sort و Merge Sort از تکنیک‌های بازگشتی برای تقسیم و حل استفاده می‌کنند.

مثال: Merge Sort


function mergeSort(arr) {
  if (arr.length <= 1) return arr;

  const mid = Math.floor(arr.length / 2);
  const left = mergeSort(arr.slice(0, mid));
  const right = mergeSort(arr.slice(mid));

  return merge(left, right);
}

function merge(left, right) {
  let result = [];
  let leftIndex = 0;
  let rightIndex = 0;

  while (leftIndex < left.length && rightIndex < right.length) {
    if (left[leftIndex] < right[rightIndex]) {
      result.push(left[leftIndex]);
      leftIndex++;
    } else {
      result.push(right[rightIndex]);
      rightIndex++;
    }
  }

  return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}

console.log(mergeSort([5, 3, 8, 4, 2])); // Output: [2, 3, 4, 5, 8]

 

در این مثال:

  • پایه: اگر آرایه تنها یک عنصر یا خالی باشد، آن را باز می‌گردانیم.

  • گام بازگشتی: آرایه را به دو زیرآرایه تقسیم کرده و هر یک را به صورت بازگشتی مرتب می‌کنیم.

 

حل مسائل با ساختارهای تودرتو

مسائل مانند محاسبه توالی فیبوناچی یا یافتن تعداد مسیرهای ممکن در شبکه‌های تودرتو نیز با استفاده از توابع بازگشتی حل می‌شوند.

مثال: توالی فیبوناچی


function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(6)); // Output: 8

 

در این مثال:

  • پایه: اگر n برابر با 0 یا 1 باشد، مقدار آن را باز می‌گردانیم.

  • گام بازگشتی: برای محاسبه fibonacci(n), مقادیر fibonacci(n-1) و fibonacci(n-2) را به صورت بازگشتی محاسبه می‌کنیم.

 

مزایا و معایب توابع بازگشتی

مزایا

  • ساده‌سازی کد: توابع بازگشتی می‌توانند کد را ساده‌تر و قابل‌فهم‌تر کنند.

  • حل مسائل پیچیده: برای مسائل با ساختار درختی یا تودرتو بسیار مناسب هستند.

 

معایب

  • مصرف حافظه بالا: توابع بازگشتی می‌توانند به دلیل ذخیره وضعیت‌های موقتی در پشته، مصرف حافظه بالایی داشته باشند.

  • مشکل کارایی: در صورتی که بازگشت‌های زیادی وجود داشته باشد، می‌تواند منجر به کاهش کارایی شود. در این موارد، استفاده از تکنیک‌هایی مانند حفظ حالت (Memoization) یا تبدیل به الگوریتم‌های غیر بازگشتی مفید است.

 

تکنیک‌های بهینه‌سازی توابع بازگشتی

حفظ حالت (Memoization)

برای بهینه‌سازی توابع بازگشتی، می‌توانیم از تکنیک حفظ حالت استفاده کنیم که در آن نتایج محاسبه شده به حافظه کش (Cache) اضافه می‌شوند تا در صورت نیاز مجدد، از نتایج ذخیره شده استفاده شود.

مثال: فیبوناچی با حفظ حالت


const memo = {};

function fibonacci(n) {
  if (n in memo) return memo[n];
  if (n <= 1) return n;
  memo[n] = fibonacci(n - 1) + fibonacci(n - 2);
  return memo[n];
}

console.log(fibonacci(6)); // Output: 8

 

تبدیل به الگوریتم‌های غیر بازگشتی

در برخی موارد، می‌توانیم الگوریتم‌های بازگشتی را به الگوریتم‌های غیر بازگشتی تبدیل کنیم تا مصرف حافظه را کاهش دهیم و کارایی را بهبود بخشیم.

مثال: فیبوناچی غیر بازگشتی


function fibonacci(n) {
  let a = 0, b = 1, temp;

  for (let i = 0; i < n; i++) {
    temp = a;
    a = b;
    b = temp + b;
  }

  return a;
}

console.log(fibonacci(6)); // Output: 8

 

نتیجه‌گیری

توابع بازگشتی ابزار قدرتمندی در برنامه‌نویسی هستند که به شما این امکان را می‌دهند که مسائل پیچیده را با استفاده از حل مسائل مشابه به صورت کوچکتر حل کنید. با درک اصول پایه‌ای توابع بازگشتی و استفاده از تکنیک‌های بهینه‌سازی، می‌توانید کدهای خود را بهبود بخشید و مسائل پیچیده را به صورت مؤثر حل کنید. از توابع بازگشتی برای حل مسائل ساختاریافته، جستجو، مرتب‌سازی و مسائل تودرتو استفاده کنید و با رعایت نکات بهینه‌سازی، کارایی و مصرف حافظه را مدیریت کنید.

پرسش و پاسخ

نظری یافت نشد

مطالب مشابه

آموزش استفاده از تگ‌های تصویری در HTML: نمایش و مدیریت تصاویر در صفحات وب
1402/05/29 20:53

آموزش استفاده از تگ‌های تصویری در HTML: نمایش و مدیریت تصاویر در صفحات وب

مطالعه بیشتر
آموزش Prepared Statement در PHP: امن‌سازی دیتابیس در برابر SQL Injection
1405/05/13 21:17

آموزش Prepared Statement در PHP: امن‌سازی دیتابیس در برابر SQL Injection

مطالعه بیشتر
آموزش جامع کار با فرم‌ها در PHP (امنیت و اعتبارسنجی طبق استاندارد گوگل)
1405/04/27 22:01

آموزش جامع کار با فرم‌ها در PHP (امنیت و اعتبارسنجی طبق استاندارد گوگل)

مطالعه بیشتر
آموزش کامل دستور switch-case در PHP (به همراه مثال‌های کاربردی)
1405/04/04 00:08

آموزش کامل دستور switch-case در PHP (به همراه مثال‌های کاربردی)

مطالعه بیشتر
آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده
1405/05/01 20:01

آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده

مطالعه بیشتر
مقدمه‌ای به رویدادها و دستورات در Vue.js: نحوه مدیریت و استفاده از v-on
1402/06/28 23:53

مقدمه‌ای به رویدادها و دستورات در Vue.js: نحوه مدیریت و استفاده از v-on

مطالعه بیشتر
آموزش صفر تا صد ساخت ماشین حساب با جاوا اسکریپت (پروژه محور و کاربردی)
1405/03/13 23:55

آموزش صفر تا صد ساخت ماشین حساب با جاوا اسکریپت (پروژه محور و کاربردی)

مطالعه بیشتر
آموزش جامع ساخت فرم ورود کاربر در PHP (براساس استانداردهای گوگل و امنیت بالا)
1405/05/14 22:03

آموزش جامع ساخت فرم ورود کاربر در PHP (براساس استانداردهای گوگل و امنیت بالا)

مطالعه بیشتر
توابع فلش (Arrow Functions) در جاوا اسکریپت: ساده‌سازی کد با استفاده از ES6
1403/06/02 20:36

توابع فلش (Arrow Functions) در جاوا اسکریپت: ساده‌سازی کد با استفاده از ES6

مطالعه بیشتر
استفاده از overflow در CSS برای مدیریت محتوای اضافی: راهنمای کامل و کاربردی
1403/08/11 21:37

استفاده از overflow در CSS برای مدیریت محتوای اضافی: راهنمای کامل و کاربردی

مطالعه بیشتر
تنظیم عرض و ارتفاع عناصر در CSS: استفاده از width، height، max و min برای کنترل دقیق اندازه‌ها
1403/08/09 21:08

تنظیم عرض و ارتفاع عناصر در CSS: استفاده از width، height، max و min برای کنترل دقیق اندازه‌ها

مطالعه بیشتر
آموزش ارث‌بری (Inheritance) در جاوا اسکریپت: نحوه استفاده از پروتوتایپ‌ها و کلاس‌ها
1403/07/28 21:20

آموزش ارث‌بری (Inheritance) در جاوا اسکریپت: نحوه استفاده از پروتوتایپ‌ها و کلاس‌ها

مطالعه بیشتر

تمامی حقوق معتلق به ناشر سایت است و کپی از آن پیگرد قانونی دارد