15-dars: Rekursiya
4-blokO'z buyruqlaringizni yasash13–16 darslar
Bu darsdan keyin siz
- rekursiv funksiyaning ikki majburiy qismini ayta olasiz
- rekursiya qanday ochilib, keyin qanday yopilishini kuzatasiz
RecursionErrorqachon va nega chiqishini bilasiz
Nazariya
“Nazariya” bo'limiga havolaIkki qism — ikkisi ham majburiy
“Ikki qism — ikkisi ham majburiy” bo'limiga havolaRekursiv funksiya o’zini chaqiradi. Buning ishlashi uchun ikki narsa kerak: bazaviy holat (o’zini chaqirmaydigan holat) va kichikroq masala (har chaqiruvda masala kichrayishi).
rekursiyarecursion
Funksiyaning o’zini chaqirishi. Masalani xuddi shu turdagi kichikroq masalaga keltirish usuli.
bazaviy holatbase case
Rekursiya to’xtaydigan holat. U bo’lmasa chaqiruvlar cheksiz davom etadi.
def faktorial(n): if n <= 1: # bazaviy holat return 1 return n * faktorial(n - 1) # kichikroq masalaprint(faktorial(4)) # 24Ikki yo’nalishda ishlaydi
“Ikki yo’nalishda ishlaydi” bo'limiga havolaRekursiya avval pastga tushadi: har chaqiruv o’zidan kichigini chaqiradi va javob kutib turadi. Bazaviy holatga yetgach, javoblar yuqoriga qaytadi va har qatlam o’z hisobini bajaradi.
Shuning uchun faktorial(4) da 4 ta chaqiruv ochiladi va 4 ta qaytish bo’ladi.
Hisob esa pastdan boshlanadi: 1, keyin 2×1, keyin 3×2, oxirida 4×6.
Stek chuqurligi cheksiz emas
“Stek chuqurligi cheksiz emas” bo'limiga havolaHar chaqiruv stekda kadr oladi (14-dars). Chaqiruvlar
juda ko’p bo’lsa stek to’ladi va Python RecursionError beradi. Standart chegara
— taxminan 1000 chaqiruv.
Bu himoya, kamchilik emas: chegarasiz bo’lsa xotira tugaydi va butun programma qulaydi. Chegaraga urilish deyarli har doim bitta narsani bildiradi — bazaviy holat yo’q yoki unga hech qachon yetilmaydi.
Rekursiya har doim kerakmi
“Rekursiya har doim kerakmi” bo'limiga havolaYo’q. Faktorial va yig’indini sikl bilan yozish osonroq va tezroq. Rekursiya tuzilma o’zi ichma-ich bo’lganda foyda beradi: papkalar, oila shajarasi, ichma-ich lug’atlar (12-dars).
Qoida sodda: masalaning shakli rekursiv bo’lsa, kod ham rekursiv bo’lsin.
Bashorat qiling
“Bashorat qiling” bo'limiga havolaAvval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
def sanoq(n): if n == 0: return print(n) sanoq(n - 1)sanoq(3)Haqiqiy natija:
3 2 1
Har chaqiruv avval o'z sonini chop etadi, keyin kichigini chaqiradi. Shuning uchun sonlar kamayib boradi.
Javobni ko'rish
3 2 1
Har chaqiruv avval o'z sonini chop etadi, keyin kichigini chaqiradi. Shuning uchun sonlar kamayib boradi.
Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
def sanoq(n): if n == 0: return sanoq(n - 1) print(n)sanoq(3)Haqiqiy natija:
1 2 3
Ikki qator joyi almashdi. Endi har chaqiruv avval pastga tushadi, chop etish esa QAYTISHDA bajariladi — natija teskari tartibda chiqadi.
Javobni ko'rish
1 2 3
Ikki qator joyi almashdi. Endi har chaqiruv avval pastga tushadi, chop etish esa QAYTISHDA bajariladi — natija teskari tartibda chiqadi.
Sinab ko’r
“Sinab ko’r” bo'limiga havolaUch variantni ketma-ket bajaring. Uchinchisi — «Bazaviy holat yo’q» — majburiy: rekursiyani tushunish uchun uning qanday buzilishini ko’rish kerak.
Rekursiya daraxti
Variantni tanlab qadamlang: chaqiruvlar ochiladi, keyin yopiladi. Klaviatura: → keyingi qadam.
Bu simulyatorda rekursiv chaqiruvlar qadamlab ochiladi va yopiladi. Chuqurlik chekinish bilan ko'rinadi, har chaqiruv javobini kutib turadi.
JavaScript'siz mashq: faktorial(4) hisoblanishini qo'lda yozib chiqing — 4 * (3 * (2 * 1)). Pastga tushish to'rt qatlam, yuqoriga qaytish ham to'rt qatlam. Uchinchi variant esa bazaviy holat yo'q bo'lsa nima bo'lishini ko'rsatadi: RecursionError.
Ikki sanoq variantini eslang: print ni rekursiv chaqiruvdan oldin yoki keyin
qo’yish natijani teskari o’zgartiradi. Sabab shu simulyatorda ko’rinadi —
pastga tushish va yuqoriga qaytish ikki alohida yo’nalish.
Xatoni toping
“Xatoni toping” bo'limiga havolaBu kod ataylab buzuq — xatoni toping
def kamayt(n): print(n) kamayt(n - 1)kamayt(3)Python shunday javob beradi:
3 2 1 0 -1 ... File "kamayt.py", line 3, in kamayt kamayt(n - 1) RecursionError: maximum recursion depth exceeded
Sababi va tuzatish
Bazaviy holat yo'q. n kamayib boradi, lekin hech qachon to'xtamaydi — manfiy sonlarga o'tib ketadi.
Ekranda sonlar chiqqani chalg’itadi: programma «ishlayotgandek» ko’rinadi. Aslida u birinchi qadamdan buzuq edi.
def kamayt(n): if n < 0: # bazaviy holat qo'shildi return print(n) kamayt(n - 1)kamayt(3)Shartni yozganda chegarani tekshirib ko’ring: if n == 0 bo’lsa ham ishlaydi,
lekin kamayt(-5) chaqirilsa yana cheksiz ketadi. n < 0 esa har qanday
kirishda to’xtaydi.
O’zingizni sinang
“O’zingizni sinang” bo'limiga havola1Rekursiv funksiyaning ikki majburiy qismi qaysi?
Javobni ko'rish
Bazaviy holat (o’zini chaqirmaydigan holat) va kichikroq masala (har chaqiruvda masala kichrayishi).
2faktorial(4) da hisob qaysi tomondan boshlanadi?
Javobni ko'rish
Pastdan: bazaviy holat 1 qaytaradi, keyin 2×1, 3×2, oxirida 4×6 = 24. Chaqiruvlar pastga tushadi, hisob yuqoriga qaytadi.
3RecursionError chiqdi. Birinchi navbatda nimani tekshirasiz?
Javobni ko'rish
Bazaviy holatni: u bormi va unga yetish mumkinmi. Deyarli har doim muammo shu ikkisidan biri.
4print ni rekursiv chaqiruvdan keyin qo'ysangiz nima o'zgaradi?
Javobni ko'rish
Chop etish qaytish yo’nalishida bajariladi, demak natija teskari tartibda chiqadi.
5Qaysi masalada rekursiya siklga afzalroq?
Javobni ko'rish
Tuzilmaning o’zi ichma-ich bo’lganda: papka ichidagi papkalar, ichma-ich lug’atlar, shajara. Oddiy yig’indi uchun sikl osonroq.
Topshiriq
“Topshiriq” bo'limiga havolaTopshiriq — darajangizni tanlang
Asos · 5–7-sinf — Vizual va aniq ko'rsatmali
sanoq(n) funksiyasini yozing: n dan 1 gacha sonlarni chop etsin. Keyin
print qatorini rekursiv chaqiruvdan keyinga ko’chirib, natija qanday
o’zgarganini daftaringizga yozing.
Mustahkam · 8–9-sinf — Matnli masala, o'zingiz tuzasiz
yigindi(n) funksiyasini rekursiya bilan yozing (1 dan n gacha). Keyin
xuddi shu funksiyani sikl bilan ham yozing. Ikki variantni solishtirib,
qaysi biri o’qishga osonroq va nega — izohda yozing. yigindi(2000)
chaqirib ko’ring va natijani izohlang.
Chuqur · 10–11-sinf — Algoritmik, chegara holatlari bilan
Ichma-ich lug’atdagi barcha sonlarni yig’adigan rekursiv funksiya yozing: lug’at ichida lug’at, ichida ro’yxat bo’lishi mumkin. Chegara holatlarini tekshiring: bo’sh lug’at, faqat sonlar, aralash qiymatlar. Keyin bir savolga javob bering: bu masalani sikl bilan yechish uchun nima qilish kerak bo’lardi?
Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.