The Stack
Rekursiya ko‘plab algoritmlarda ishlatiladigan kodlash texnikasi hisoblanadi.
The stack
Ushbu bo'lim qo'ng'iroqlar to'plamini qamrab oladi. Bu dasturlashda muhim tushuncha. Qo'ng'iroqlar to'plami umumiy dasturlashda muhim tushunchadir va uni rekursiyadan foydalanganda tushunish ham muhimdir.
Aytaylik, siz barbekyu tashlayapsiz. Siz barbekyu uchun qilinadigan ishlar ro'yxatini yopishqoq yozuvlar to'plami shaklida saqlaysiz.
Esingizdami, biz massivlar va ro'yxatlar haqida gaplashganimizda va sizda vazifalar ro'yxati bor edi? Roʻyxatning istalgan joyiga vazifalarni qoʻshishingiz yoki tasodifiy elementlarni oʻchirishingiz mumkin. Yopishqoq qog'ozlar to'plami ancha sodda. Elementni qo'shganingizda, u ro'yxatning yuqori qismiga qo'shiladi. Biror narsani o'qiyotganingizda, siz faqat eng yuqori elementni o'qiysiz va u ro'yxatdan o'chiriladi. Shunday qilib, sizning vazifalar ro'yxati faqat ikkita amaldan iborat: surish (qo'shish) va pop (o'chirish va o'qish).
Keling, bajariladigan ishlar ro'yxatini amalda ko'rib chiqaylik
Ushbu ma'lumotlar strukturasi stek deb ataladi. Stack oddiy ma'lumotlar strukturasidir. Siz o'zingiz bilmagan holda butun vaqt davomida stekdan foydalandingiz!
The call stack
Sizning kompyuteringiz qo'ng'iroqlar to'plami deb ataladigan ichki stekdan foydalanadi. Keling, buni amalda ko'rib chiqaylik. Mana oddiy funksiya:
Python
Golang
Bu funksiya sizni kutib oladi va keyin yana ikkita funksiyani chaqiradi. Mana bu ikkita funktsiya:
Python
Golang
Funktsiyani chaqirganingizda nima sodir bo'lishini ko'rib chiqaylik
Aytaylik, siz print("maggie")
deb chaqirasiz. Birinchidan, kompyuteringiz ushbu funktsiya chaqiruvi uchun xotira qutisini ajratadi.
Endi xotiradan foydalanamiz. O'zgaruvchining nomi "maggie" ga o'rnatiladi. Bu xotirada saqlanishi kerak
Har safar funktsiya chaqiruvi qilganingizda, kompyuteringiz ushbu qo'ng'iroq uchun barcha o'zgaruvchilar uchun qiymatlarni shunday xotirada saqlaydi. Keyin, hello, maggie!
, chop etasiz! Keyin siz greet2("maggie")
ga qo'ng'iroq qilasiz. Shunga qaramay, sizning kompyuteringiz ushbu funktsiya chaqiruvi uchun xotira qutisini ajratadi.
Sizning kompyuteringiz ushbu qutilar uchun stekdan foydalanmoqda. Ikkinchi quti birinchisining ustiga qo'shiladi. Siz chop etasizmi, how are you, maggie?
Keyin siz funktsiya chaqiruvidan qaytasiz. Bu sodir bo'lganda, stek ustidagi quti chiqib ketadi.
Endi stekdagi eng yuqori quti greet
funksiyasi uchun, ya'ni siz greet
funksiyasiga qaytdingiz. greet2
funksiyasini chaqirganingizda greet
funksiyasi qisman bajarildi. Bu bo'lim ortidagi katta g'oya: funksiyani boshqa funksiyadan chaqirganingizda, chaqiruvchi funksiya qisman tugallangan holatda to'xtatiladi. Ushbu funktsiya uchun o'zgaruvchilarning barcha qiymatlari hali ham xotirada saqlanadi. Endi greet2
funksiyasi bilan ishlashni tugatganingizdan so'ng, greet
funksiyasiga qaytdingiz va to'xtagan joydan davom etasiz. Avval getting ready to say bye….
chop etiladi. Siz bye
funksiyasini chaqirasiz.
Ushbu funktsiya uchun quti stekning yuqori qismiga qo'shiladi. Keyin ok bye
chop etiladi va funktsiya chaqiruvidan qaytish.
Va siz greet
funksiyasiga qaytdingiz. Boshqa hech narsa qilish shart emas, shuning uchun siz greet
funksiyasidan ham qaytasiz. Bir nechta funksiyalar uchun o'zgaruvchilarni saqlash uchun foydalaniladigan bu stek chaqiruv stegi deb ataladi.
EXERCISE
3.1 Aytaylik, men sizga shunday qo'ng'iroqlar to'plamini ko'rsataman
Ushbu qo'ng'iroqlar to'plamiga asoslanib, menga qanday ma'lumot bera olasiz? Keling, qo'ng'iroqlar to'plamini rekursiv funksiya bilan ishlayotganini ko'rib chiqaylik.
The call stack with recursion
Rekursiv funktsiyalar qo'ng'iroqlar to'plamidan ham foydalanadi! Keling, buni faktorial
funksiya bilan amalda ko'rib chiqaylik. faktorial(5)
5! sifatida yoziladi va u quyidagicha aniqlanadi: 5! = 5 _ 4 _ 3 _ 2 _ 1. Xuddi shunday, faktorial(3)
3 _ 2 _ 1 ga teng. Mana, sonning faktorialini hisoblash uchun rekursiv funksiya:
Python
Golang
Endi siz fakt(3)
ni chaqirasiz. Keling, ushbu qo'ng'iroqni satr bo'ylab ko'rib chiqamiz va stek qanday o'zgarganini ko'ramiz. Esingizda bo'lsin, stekdagi eng yuqori quti sizga hozirda qaysi fact
ni chaqirayotganingizni ko'rsatadi.
E'tibor bering, har bir fact
ga qo'ng'iroq o'zining x
nusxasiga ega. Siz boshqa funksiyaning x
nusxasiga kira olmaysiz.
Rekursiyada stek katta rol o'ynaydi. Ochilish misolida kalitni topish uchun ikkita yondashuv mavjud edi. Mana yana birinchi yo'l.
Shunday qilib, siz qidirish uchun qutilar to'plamini yaratasiz, shuning uchun siz har doim qanday qutilarni qidirishingiz kerakligini bilasiz.
Ammo rekursiv yondashuvda hech qanday qoziq yo'q.
Agar qoziq bo'lmasa, sizning algoritmingiz qanday qutilarni ko'rib chiqishingiz kerakligini qanday biladi? Mana bir misol:
Ushbu nuqtada qo'ng'iroqlar to'plami shunday ko'rinadi.
"Qutilar uyumi" stekda saqlanadi! Bu yarim tugallangan funksiya qo'ng'iroqlari to'plami bo'lib, ularning har biri ko'rib chiqilishi kerak bo'lgan o'zining yarim to'liq ro'yxatiga ega. Stackdan foydalanish qulay, chunki siz o'zingiz qutilar to'plamini kuzatib borishingiz shart emas - stek buni siz uchun qiladi.
Stackdan foydalanish qulay, ammo xarajati bor: barcha ma'lumotlarni saqlash juda ko'p xotirani egallashi mumkin. Ushbu funktsiya chaqiruvlarining har biri biroz xotirani egallaydi va sizning stekingiz juda baland bo'lsa, bu sizning kompyuteringiz ko'plab funktsiya chaqiruvlari uchun ma'lumotni saqlayotganini anglatadi. Bu vaqtda sizda ikkita variant bor:
- Buning o'rniga loopdan foydalanish uchun kodingizni qayta yozishingiz mumkin.
- Siz quyruq rekursiyasi deb ataladigan narsadan foydalanishingiz mumkin. Bu ilg'or rekursiya mavzusi bo'lib, bu kitobning doirasiga kirmaydi. Bundan tashqari, hamma emas, faqat ba'zi tillar tomonidan qo'llab-quvvatlanadi.
EXERCISE
3.2 Faraz qilaylik, siz tasodifan abadiy ishlaydigan rekursiv funktsiyani yozdingiz. Ko'rib turganingizdek, kompyuteringiz har bir funktsiya chaqiruvi uchun stekga xotira ajratadi. Sizning rekursiv funktsiyangiz abadiy ishlaganda stek bilan nima sodir bo'ladi?