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 ကို မမေ့ပါနဲ့ပေါ့။ 🙂