ภาพรวม
Recursive Method (เมธอดเรียกตัวเอง) คือ เมธอดที่เรียกตัวเองภายในตัวเอง เพื่อแก้ปัญหาที่สามารถแบ่งเป็น Sub-problems ที่มีโครงสร้างเดียวกัน ต้องมี Base Case (กรณีฐาน) เพื่อหยุด Recursion ไม่งั้นจะเกิด Stack Overflow
ตัวอย่าง: Factorial (แฟกทอเรียล)
n! = n × (n-1) × ... × 1, โดย 0! = 1, 1! = 1
using System;
namespace MyApplication
{
class Factorial
{
public int Calculate(int n)
{
// Base Case: หยุด Recursion
if (n <= 1)
return 1;
// Recursive Case: เรียกตัวเองด้วย n-1
return n * Calculate(n - 1);
}
static void Main(string[] args)
{
int value = 5;
Factorial fact = new Factorial();
int result = fact.Calculate(value);
Console.WriteLine("{0}! = {1}", value, result); // 5! = 120
Console.ReadLine();
}
}
}ผลลัพธ์
5! = 120
การทำงานของ Recursive Factorial (5!)
Calculate(5) = 5 * Calculate(4) = 5 * (4 * Calculate(3)) = 5 * 4 * (3 * Calculate(2)) = 5 * 4 * 3 * (2 * Calculate(1)) = 5 * 4 * 3 * 2 * 1 // Base Case: Calculate(1) = 1 = 120
โครงสร้าง Recursive Method
ReturnType RecursiveMethod(Parameters)
{
// 1. Base Case(s) - เงื่อนไขหยุด (สำคัญที่สุด!)
if (baseCondition)
return baseValue;
// 2. Recursive Case - เรียกตัวเองด้วย Problem Size ที่เล็กลง
return Combine(CurrentStep, RecursiveMethod(SimplifiedParameters));
}ตัวอย่างเพิ่มเติม: Fibonacci
public int Fibonacci(int n)
{
if (n <= 1) return n; // Base Cases: F(0)=0, F(1)=1
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
// หมายเหตุ: วิธีนี้ช้า O(2^n) ควรใช้ Memoization หรือ Iterativeการปรับปรุงประสิทธิภาพ: Memoization
private Dictionarymemo = new Dictionary (); public int FibonacciMemo(int n) { if (n <= 1) return n; if (memo.TryGetValue(n, out int cached)) return cached; int result = FibonacciMemo(n - 1) + FibonacciMemo(n - 2); memo[n] = result; return result; }
Iterative Version (แปลง Recursion เป็น Loop)
public int FactorialIterative(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
result *= i;
return result;
}
// Stack Overflow Risk: Recursion Depth ~ 10,000-100,000 (ขึ้นอยู่กับ Stack Size)
// Iterative ไม่มีปัญหา Stack Overflowข้อสังเกตสำคัญ
- Base Case บังคับ - ไม่มี = Infinite Recursion = StackOverflowException
- แต่ละ Recursive Call ใช้ Stack Frame ~ 1KB → จำกัดความลึก
- Tail Recursion Optimization: C# Compiler/CLR ไม่รับประกัน (ต่างจาก F#)
- ใช้ Recursion เมื่อ: Tree/Graph Traversal, Divide & Conquer, Backtracking, Parser
- หลีกเลี่ยง Recursion เมื่อ: Iterative เขียนง่ายเท่ากัน, Performance Critical, Deep Recursion
- C# 7.0+ ใช้
ref returnและlocal functionsช่วย Recursion ได้