Programming လေ့လာတဲ့သူတိုင်း တစ်နေ့နေ့ ကြုံရမယ့် စကားလုံး — recursion။
လွယ်လွယ်ပြောရရင် — function တစ်ခုက ကိုယ့်ဟာကိုယ် ပြန်ခေါ်သုံးတာ။
မှန်နှစ်ချပ် မျက်နှာချင်းဆိုင်
ဆံပင်ညှပ်ဆိုင်မှာ ထိုင်ဖူးတယ်မဟုတ်လား။ ရှေ့မှန်နဲ့ နောက်မှန် မျက်နှာချင်းဆိုင် ထားတော့ မှန်ထဲမှာ ကိုယ့်ပုံက ထပ်ထပ်ပြီး အဆုံးမသတ် ပေါ်နေတာ မြင်ဖူးမယ်။
Recursion လည်း ဒီအတိုင်းပဲ — function က သူ့ကိုယ်သူ ခေါ်တယ်၊ အဲဒီအခေါ်ခံရတဲ့ function က သူ့ကိုယ်သူ ထပ်ခေါ်တယ်… ဒီလို ထပ်ထပ်သွားတာ။
တကယ့် ဥပမာ — Factorial
သင်္ချာမှာ factorial ဆိုတာ ရှိတယ် — 5! = 5 × 4 × 3 × 2 × 1 = 120။
Recursion နဲ့ တွေးရင် ဒီလို —
factorial(5) = 5 × factorial(4)factorial(4) = 4 × factorial(3)factorial(3) = 3 × factorial(2)factorial(2) = 2 × factorial(1)factorial(1) = 1 — ဒီမှာ ရပ်တယ်
တွေ့လား? ပြဿနာကြီးကို ပြဿနာသေးလေး အဖြစ်ပြောင်းပြီး ကိုယ့်ဟာကိုယ် ထပ်ခေါ်သွားတာ။ နောက်ဆုံး အသေးဆုံးအဆင့် (factorial(1)) ရောက်မှ ရပ်ပြီး အဖြေတွေ ပြန်တက်လာတယ်။
Code နဲ့ ရေးရင် ဒီလို —
function factorial(n) {
if (n == 1) return 1; // ရပ်တဲ့ အမှတ်
return n * factorial(n-1); // ကိုယ့်ဟာကိုယ် ပြန်ခေါ်
}
Base Case — ရပ်တဲ့ အမှတ်
အရေးအကြီးဆုံး အစိတ်အပိုင်းက if (n == 1) return 1; ဆိုတဲ့ စာကြောင်းပဲ။ ဒါကို base case လို့ ခေါ်တယ် — recursion ရပ်ရမယ့် အမှတ်။
Base case မရှိရင် ဘာဖြစ်မလဲ? Function က သူ့ကိုယ်သူ အဆုံးမသတ် ခေါ်နေမယ် — မှန်ထဲက ပုံလို infinity ဖြစ်သွားမယ်။ ကွန်ပျူတာက memory ကုန်သွားပြီး stack overflow error နဲ့ crash သွားလိမ့်မယ်။
ဒါကြောင့် recursion ရေးတိုင်း အရင်ဆုံး မေးရမယ့် မေးခွန်းက — “ဘယ်အချိန်မှာ ရပ်မှာလဲ?”
ဘယ်အချိန်မှာ သုံးသင့်လဲ?
အသိုက်ပုံစံ ပြဿနာတွေ — folder ထဲမှာ folder၊ အဲဒီထဲမှာ ထပ် folder… လို အဆင့်ဆင့် ရှိတဲ့ အရာတွေ။
သစ်ပင် (tree) ပုံစံ data — comment တွေရဲ့ reply၊ reply ရဲ့ reply…
ခွဲပြီး ဖြေရှင်းလို့ရတဲ့ ပြဿနာ — ကြီးတာကို သေးသေးလေးတွေ ခွဲလို့ရရင်။
ဒါပေမဲ့ အရာတိုင်းကို recursion နဲ့ မရေးသင့်ဘူး။ ရိုးရိုး loop နဲ့ ရရင် loop က ပိုမြန်ပြီး memory လည်း ပိုသက်သာတယ်။
Recursion ဆိုတာ လက်နက်တစ်မျိုး — မှန်တဲ့နေရာမှာ သုံးရင် တော်တော် လှတယ်၊ မှားတဲ့နေရာမှာ သုံးရင် တော်တော် ပျက်တယ်။ စမ်းကြည့်ပါ၊ base case ကို မမေ့ပါနဲ့ပေါ့။ 🙂