آموزش رایگان جاوا اسکریپت (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

 

نتیجه‌گیری

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

پرسش و پاسخ

نظری یافت نشد

مطالب مشابه

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

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

مطالعه بیشتر
راهنمای کامل لیست‌ها در HTML: آموزش انواع و اصول سئو
1402/05/20 22:02

راهنمای کامل لیست‌ها در HTML: آموزش انواع و اصول سئو

مطالعه بیشتر
آموزش کامل و اصولی اتصال PHP به پایگاه داده MySQL (به روش PDO و MySQLi)
1405/05/04 23:34

آموزش کامل و اصولی اتصال PHP به پایگاه داده MySQL (به روش PDO و MySQLi)

مطالعه بیشتر
آموزش Directive‌ های Vue.js | استفاده از v-model، v-bind و v-show با مثال
1404/09/23 21:10

آموزش Directive‌ های Vue.js | استفاده از v-model، v-bind و v-show با مثال

مطالعه بیشتر
آموزش کامل include و require در PHP + تفاوت‌های کلیدی و کاربردی
1405/05/01 20:28

آموزش کامل include و require در PHP + تفاوت‌های کلیدی و کاربردی

مطالعه بیشتر
سیر تا پیاز عملگرهای ریاضی در PHP + مثال‌های کاربردی
1405/03/24 01:21

سیر تا پیاز عملگرهای ریاضی در PHP + مثال‌های کاربردی

مطالعه بیشتر
آموزش ایجاد و حذف المان‌های DOM به صورت داینامیک با جاوا اسکریپت: راهنمای جامع و کاربردی
1403/08/02 21:21

آموزش ایجاد و حذف المان‌های DOM به صورت داینامیک با جاوا اسکریپت: راهنمای جامع و کاربردی

مطالعه بیشتر
آموزش کار با flex-grow، flex-shrink و flex-basis در CSS Flexbox: مدیریت اندازه و فضای عناصر
1403/08/11 20:50

آموزش کار با flex-grow، flex-shrink و flex-basis در CSS Flexbox: مدیریت اندازه و فضای عناصر

مطالعه بیشتر
آموزش جامع توابع داخلی و پرکاربرد PHP + مثال‌های عملی
1405/04/16 01:18

آموزش جامع توابع داخلی و پرکاربرد PHP + مثال‌های عملی

مطالعه بیشتر
آموزش جامع و اصولی جستجو در دیتابیس با PHP و MySQL (مطابق استانداردهای گوگل)
1405/05/13 21:26

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

مطالعه بیشتر
آموزش فیلتر کردن داده‌ها در PHP با توابع filter_var و preg_match
1405/05/13 21:29

آموزش فیلتر کردن داده‌ها در PHP با توابع filter_var و preg_match

مطالعه بیشتر
آموزش جامع توابع در جاوا اسکریپت: نحوه تعریف، فراخوانی و بازگشت مقادیر
1402/11/02 23:23

آموزش جامع توابع در جاوا اسکریپت: نحوه تعریف، فراخوانی و بازگشت مقادیر

مطالعه بیشتر

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