A function that calls itself to solve smaller instances of the same problem.
تخيل إنك واقف بين مرايتين متقابلتين... هتشوف انعكاس جوه انعكاس جوه انعكاس... لانهاية!
الـ Recursion نفس الفكرة: Function بتنادي نفسها، بس لازم يكون فيه نقطة توقف!
الشرط اللي يخلي الـ function توقف عن نداء نفسها
⚠️ من غيرها = Stack Overflow!
الـ function بتنادي نفسها بـ input أصغر
لازم نقرب من الـ Base Case!
كل مرة الـ function بتنادي نفسها، الكمبيوتر بيحفظ الحالة الحالية في Call Stack (زي كومة أطباق).
مثال: حساب المضروب (Factorial)
n! = ضرب كل الأرقام من 1 لـ n
5! = 5 × 4 × 3 × 2 × 1 = 120
3! = 3 × 2 × 1 = 6
1! = 1
0! = 1 (بالتعريف)
Base Case: 0! = 1
Recursive: n! = n × (n-1)!
5! = 5 × 4!
4! = 4 × 3!
... وهكذا لحد ما نوصل لـ 0!
Call Stack will appear here
function factorial(n) {
// Base Case: stop here!
if (n === 0) {
return 1;
}
// Recursive Case: n! = n × (n-1)!
return n * factorial(n - 1);
}
مثال: متتالية فيبوناتشي
كل رقم = مجموع الرقمين اللي قبله
Base Cases:
fib(0) = 0
fib(1) = 1
Recursive:
fib(n) = fib(n-1) + fib(n-2)
⚠️ تحذير!
الـ naive recursive Fibonacci بطيء جداً: O(2ⁿ)!
لأن بيحسب نفس القيم كتير.
Recursion tree will appear here
// ⚠️ Naive approach - O(2ⁿ)
function fib(n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
// ✅ Better: Memoization - O(n)
function fibMemo(n, memo = {}) {
if (n <= 1) return n;
if (memo[n]) return memo[n];
memo[n] = fibMemo(n-1, memo) + fibMemo(n-2, memo);
return memo[n];
}
مثال بسيط: العد التنازلي
function countdown(n) {
// Base Case
if (n <= 0) {
console.log("Blastoff! 🚀");
return;
}
// Recursive Case
console.log(n);
countdown(n - 1);
}
countdown(5);
// Output: 5, 4, 3, 2, 1, Blastoff! 🚀
Countdown will appear here
| المقارنة | Recursion | Iteration (Loop) |
|---|---|---|
| الكود | أنظف وأقصر عادة | أطول أحياناً |
| الذاكرة | O(n) - Call Stack | O(1) - أقل |
| الأداء | Overhead من النداءات | أسرع عادة |
| أفضل لـ | Trees, Graphs, Divide & Conquer | Simple loops, Fixed iterations |