Rekursiya va stek
Rekursiya โ bu masalani o'ziga o'xshash, ammo soddaroq qism-masalalarga bo'lib yechish uslubi. Bunda funksiya o'zini o'zi chaqiradi. Bu dasturlashning eng go'zal va kuchli g'oyalaridan biri.
Rekursiya g'oyasi
Funksiya boshqa funksiyani chaqirishi mumkin. Agar funksiya o'zini o'zi chaqirsa โ bu rekursiya deb ataladi.
Rekursiyaning asosiy g'oyasi shunda: katta masalani biroz kichraytiramiz va o'sha kichik masalani o'sha funksiyaning o'zi orqali yechamiz. Bu jarayon masala shu qadar kichrayguncha davom etadiki, oxir-oqibat javob to'g'ridan-to'g'ri ma'lum bo'lib qoladi.
Demak, har qanday rekursiv funksiyada ikkita holat bo'ladi:
- Asos (baza) holati โ masala shu qadar sodda bo'ladiki, javobni darhol qaytaramiz. Bu rekursiyani to'xtatadigan holat;
- Rekursiv holat โ masalani kichraytirib, funksiyaning o'zini yana chaqiramiz.
RangeError: Maximum call stack size exceeded).Birinchi misol: daraja (pow)
x sonini n-darajaga ko'taruvchi funksiya yozamiz, ya'ni xni o'zini n marta ko'paytiramiz. Buni ikki xil ko'rish mumkin.
Iterativ (takroriy) yo'l โ oddiy for sikli bilan:
Rekursiv yo'l โ masalani soddalashtiramiz. E'tibor bering: pow(x, n) ni x * pow(x, n-1) shaklida yozish mumkin:
pow(2, 3) chaqirilganda ijro quyidagicha "pastga tushadi" va so'ng "yuqoriga qaytadi":
pow(2, 3)= 2 *pow(2, 2)pow(2, 2)= 2 *pow(2, 1)pow(2, 1)= 2 (asos holati, rekursiya to'xtaydi)- Endi orqaga qaytamiz: 2 * 2 = 4, so'ng 2 * 4 = 8.
Ijro steki (execution stack)
Har bir funksiya chaqirilganda, uning ichki ma'lumotlari โ o'zgaruvchilari, argumentlari va hozir ijro qilinayotgan qatorning o'rni โ maxsus ichki tuzilmada saqlanadi. Bu tuzilma ijro steki (execution context stack) deb ataladi.
Har bir chaqiruv uchun alohida ijro konteksti (execution context) yaratiladi va u stekning ustiga qo'yiladi. Funksiya boshqa funksiyani chaqirsa:
- Joriy funksiyaning ijrosi pauza qilinadi;
- Uning konteksti stekda saqlanib turadi;
- Yangi chaqiruv uchun yangi kontekst stek ustiga qo'yiladi;
- Yangi chaqiruv tugagach, uning konteksti stekdan olib tashlanadi va pauza qilingan kontekst davom etadi.
pow(2, 3) uchun stek eng chuqur nuqtada uchta kontekstni saqlaydi: pow(2,3), pow(2,2) va pow(2,1). Asos holatiga yetgach, ular birma-bir stekdan tozalanib boradi.
Ikkinchi misol: faktorial
Faktorial n! โ 1 dan n gacha bo'lgan sonlarning ko'paytmasi: n! = 1 * 2 * 3 * ... * n. Uni rekursiv shaklda juda chiroyli yozish mumkin, chunki n! = n * (n-1)!:
Bu yerda asos holati n == 0 bo'lib, 1 qaytaradi (matematikada 0! = 1). Qolgan barcha holatlar rekursiv ravishda soddalashadi.
Uchinchi misol: Fibonachchi sonlari
Fibonachchi ketma-ketligi 0 va 1 dan boshlanadi, keyingi har bir son avvalgi ikkitasining yig'indisiga teng: 0, 1, 1, 2, 3, 5, 8, 13, .... Ta'rifning o'zi rekursiv: F(n) = F(n-1) + F(n-2).
fib(n) bir xil qiymatlarni ko'p marta qayta hisoblaydi. Masalan fib(35) allaqachon sezilarli sekinlashadi. Amalda buni sikl yoki eslab qolish (memoization) bilan tezlashtiradilar. Ammo o'rganish uchun bu misol rekursiyaning tabiatini juda yaxshi ko'rsatadi.Tezroq, iterativ variant esa oddiy siklda ishlaydi:
Rekursiv ma'lumot tuzilmalari
Rekursiya faqat funksiyalarga xos emas. Ba'zi ma'lumot tuzilmalari ham rekursiv tabiatga ega โ ular o'z ichida o'ziga o'xshash qismlarni saqlaydi.
- Bo'linmaydigan (nested) obyektlar โ masalan kompaniya bo'limlari, ularning ichida yana ichki bo'limlar bor;
- Daraxt (tree) โ HTML hujjatning DOM tuzilmasi, fayl tizimidagi papkalar;
- Bog'langan ro'yxat (linked list) โ har bir element keyingi elementga ishora qiladi.
Bunday tuzilmalarni rekursiv funksiya bilan qayta ishlash juda tabiiy. Misol uchun, ichma-ich joylashgan bo'limlardagi umumiy maoshni sanaymiz:
Xulosa
- Rekursiya โ funksiyaning o'zini o'zi chaqirishi orqali masalani soddaroq qism-masalalarga bo'lib yechish;
- Har bir rekursiv funksiyada asos holati (to'xtash) va rekursiv holat (kichraytirish) bo'lishi shart;
- Har bir chaqiruv ijro steki da yangi kontekst yaratadi; chuqurlik cheklangan;
- Rekursiv yechim ko'pincha qisqa va tushunarli, iterativ yechim esa odatda tezroq;
- Daraxt, ichma-ich obyektlar kabi rekursiv tuzilmalar rekursiya bilan tabiiy qayta ishlanadi.