780_23 gurux talabasi: Xafizov Fozilbek Mustaqil ish. Rekursiya va uni dasturlashda ishlatish Kirish. Rekursiya – bu funksiyaning o‘z-o‘zini chaqirishi orqali masalalarni yechish usuli. Dasturlashda bu yondashuv ko‘pincha tabiiy va soddalashtirilgan kod yaratishga imkon beradi. Rekursiya yordamida murakkab masalalarni oddiyroq qismlarga ajratish va yechish qulay bo‘ladi. Ushbu usul ko‘p algoritmlarning, jumladan, qidiruv, saralash va matematik masalalarni hal qilishning asosini tashkil etadi. Rekursiyaning dasturlashdagi o‘rni nafaqat masalalarni hal qilishda qulaylik yaratishda, balki dasturchilarga abstrakt fikrlash ko‘nikmalarini shakllantirishda ham katta ahamiyatga ega. Reja: 1.Rekursiyaning asosiy tamoyillari 2.Rekursiyaning dasturlashda qo‘llanilishi 3.Rekursiyani optimallashtirish 4.Xulosa Rekursiyaning Asosiy Tamoyillari Rekursiya – bu funksiyaning o‘z-o‘zini chaqirishi orqali masalani yechish usuli. Bu yondashuv masalalarni kichik qismlarga bo‘lish va ularni qayta-qayta hal qilish tamoyiliga asoslanadi. Rekursiya muvaffaqiyatli ishlashi uchun quyidagi uch asosiy tamoyilga amal qilinadi: Bazaviy holat – bu rekursiyaning tugash sharti. Funksiyaning bazaviy holati bajarilganda, rekursiv chaqiruv to‘xtatiladi va funksiya o‘z ishini yakunlab, aniq natijani qaytaradi. Bazaviy holat quyidagi maqsadlarga xizmat qiladi: 1. Rekursiyani cheksiz davom etishidan himoya qiladi. 2. Masalani eng oddiy shaklda hal qilishni ta’minlaydi. Bazaviy holatning muhimligi: Har qanday rekursiv funksiya kamida bitta bazaviy holatga ega bo‘lishi shart. Agar bazaviy holat noto‘g‘ri aniqlansa yoki umuman ko‘rsatilmasa, funksiya cheksiz ravishda o‘zini chaqiradi, bu esa dastur xotira chegarasini (stack memory) to‘ldirishiga olib keladi. Rekursiv chaqiriq – bu funksiyaning o‘zini o‘zi chaqirish jarayoni. Rekursiv chaqiriqda masala kichikroq yoki oddiyroq shaklga o‘tkazilib, funksiya ushbu shaklni hal qilish uchun o‘zini qayta chaqiradi. Rekursiv chaqiriqning asosiy xususiyati – har bir chaqiriq masalani bazaviy holatga yaqinlashtiradi. Bu jarayon davomida funksiya har bir qadamda masalani soddalashtiradi va oxir-oqibat bazaviy holatga yetadi. Rekursiv chaqiriqning talablari: 1. Masala har bir chaqiriqda kichrayishi yoki soddalashishi shart. 2. Rekursiv chaqiriq orqali yechimning umumiy algoritmi aniqlanishi kerak. 3. Agar masala har bir chaqiriqda bazaviy holatga yaqinlashmasa, rekursiv chaqiriqlar cheksiz davom etadi, bu esa dastur xatoga uchrashiga olib keladi. Rekursiv funksiyani yozishda uning cheksiz davom etishidan qochish juda muhimdir. Bu quyidagilar orqali amalga oshiriladi. Har bir rekursiv funksiya uchun aniq va to‘g‘ri bazaviy holat aniqlanadi. Har bir rekursiv chaqiriqda masala bazaviy holatga yaqinlashtiriladi. 1-Reja. Agar ushbu tamoyillar buzilsa, rekursiv chaqiruvlar stack xotirasida cheksiz ko‘payib, dastur "stack overflow" xatoligini keltirib chiqaradi. Cheksiz rekursiyaga sabab bo‘ladigan omillar: 1. Bazaviy holatning yo‘qligi yoki noto‘g‘ri aniqlanishi. 2. Rekursiv chaqiruvda masalaning bazaviy holatga yaqinlashmasligi. Rekursiyaning printsipi Rekursiya ikki asosiy bosqichda ishlaydi: 1.Chaqiruv bosqichi: Rekursiv funksiya o‘zini qayta chaqiradi va bu jarayon bazaviy holatga yetguncha davom etadi. Har bir chaqiruv yangi masalani yechishga qaratilgan bo‘lib, dastlabki masala kichik qismlarga bo‘linadi. 2.Natijalarni qaytarish bosqichi: Bazaviy holatga yetilgandan so‘ng, rekursiv chaqiruvlar tugaydi va funksiyaning natijalari har bir chaqiruvdan qaytariladi. Bu jarayon "stack" xotirasidagi chaqiruvlarni boshqaradi, har bir chaqiruv o‘z natijasini qaytarib asosiy funksiya zanjiriga ulaydi. Rekursiyaning Asosiy Afzalliklari 1. Masalalarni yechish jarayonini oddiy va tabiiy tarzda ifodalashga imkon beradi. 2. Dastur kodini soddalashtiradi, ayniqsa, murakkab algoritmlar uchun. 3. Muammolarni kichik qismlarga bo‘lish orqali modullilikni ta’minlaydi. Rekursiyaning Cheklovlari 1. Xotira iste’moli yuqori bo‘lishi mumkin, chunki har bir rekursiv chaqiruv yangi stack kadrini hosil qiladi. 2. Cheksiz rekursiyadan qochish uchun ehtiyotkorlik talab etadi. 3. Katta o‘lchamli muammolar uchun iteratsion yondashuv ba’zida samaraliroq bo‘ladi. 4. Rekursiya tamoyillarini chuqur tushunish va ularga rioya qilish murakkab masalalarni hal qilishda samarali vositadir. 2-Reja. Rekursiya dasturlashda bir funksiyaning o‘zini-o‘zi chaqirish tamoyiliga asoslangan usuldir. Bu yondashuv murakkab masalalarni kichikroq, o‘xshash masalalarga bo‘lishga yordam beradi va ayniqsa, ma’lum turdagi muammolarni hal qilishda samarali hisoblanadi. Rekursiyaning asosiy xususiyatlari: 1.Bazaviy holat (Base Case): Har bir rekursiv funksiya cheksiz chaqiruvdan qochish uchun biror shart (odatda bazaviy holat) bilan tugashi kerak. Bazaviy holatda funksiya rekursiyani to‘xtatib, natijani qaytaradi. 2.Rekursiv chaqiriq: Funksiya o‘zining kichikroq versiyasini chaqiradi va bunda asosiy masala bazaviy holat sari qisqaradi. Rekursiya qayerda ishlatiladi? 1.Matematik formulalar: Masalan, faktorial, Fibonachchi sonlari, kuchli yoki eksponensial hisob-kitoblarni rekursiya orqali yechish mumkin. 2.Daraxt va graf tuzilmalarida: Daraxtlar yoki graf kabi ierarxik ma’lumotlarni qayta ishlashda rekursiya tabiiy yechimdir. Tugunlarni yoki yo‘llarni o‘qishda, rekursiya yordamida strukturaga mos ravishda ishlash mumkin. 3.Ajrat va hukmronlik qil yondashuvi: Katta masalalarni kichik bo‘laklarga bo‘lib ishlashga asoslangan algoritmlar (masalan, tez tartiblash, birlashma tartiblash) rekursiyani qo‘llaydi. 4.Kombinatorika va o‘yin nazariyalari: Kombinatsiyalar va tartiblarni generatsiya qilishda, masalan, barcha mumkin bo‘lgan yo‘llar yoki o‘yin harakatlarini aniqlashda. 5.Rekursiv tuzilmalar: O‘z ichida takrorlanuvchi tuzilmalarga ega masalalarda (masalan, fraktallar yoki arifmetik ketma-ketliklar) rekursiya tabiiy yechim beradi. Rekursiyaning afzalliklari: 1.Qisqalik va aniqlik: Rekursiv algoritmlar ko‘pincha oddiy va tushunarli yoziladi, ayniqsa murakkab tuzilmalarga ishlov berishda. 2.Tabiiylik: Ierarxik yoki takroriy masalalarda rekursiya mantiqiy yondashuvni taqdim etadi. Rekursiyaning kamchiliklari: 1.Stek xotirasi: Har bir rekursiv chaqiriq yangi funksiya chaqiruvi uchun stekda joy egallaydi. Agar rekursiya chuqur bo‘lsa, bu stek to‘lib qolishiga olib kelishi mumkin. 2.Samaradorlik: Ba’zi rekursiv algoritmlar qayta hisob-kitoblar ko‘p bo‘lishi sababli samarasiz ishlaydi. Bunda dinamik dasturlash kabi optimallashtirish yondashuvlari kerak bo‘lishi mumkin. 3.Tushunish qiyin bo‘lishi: Murakkab rekursiv funksiyalarni tushunish va ulardagi xatolarni topish ba’zida qiyin bo‘lishi mumkin. Rekursiya odatda murakkab masalalarni sodda tushuntirishga imkon beruvchi vosita sifatida ishlatiladi, ammo undan foydalanganda bazaviy holatni va samaradorlikni hisobga olish muhimdir. 3-Reja. Rekursiyani optimallashtirish — bu rekursiv algoritmlarning samaradorligini oshirishga qaratilgan jarayon bo‘lib, asosan hisoblash va xotira sarfini kamaytirishga yordam beradi. Rekursiv yondashuvlarning ba'zi kamchiliklari, masalan, ko‘p marta bir xil qiymatlarni qayta hisoblash yoki stekda joy to‘ldirib, xotira limitlariga yetish mumkin. Optimallashtirish bu muammolarni hal qilishga qaratilgan. Rekursiyaning optimallashtirilishida asosiy maqsadlar quyidagilar: 1. Memoizatsiya (Memoization) Memoizatsiya — bu bir necha bor qaytariladigan hisoblashlarni oldini olish uchun natijalarni saqlab qo‘yish usulidir. Har safar rekursiv chaqiriq bajarilganida, hisoblangan natija biron bir joyda saqlanadi, va agar shu natija keyinchalik yana talab qilinsa, uni qayta hisoblash o‘rniga saqlangan qiymat qaytariladi. Bu yondashuv vaqtni tejaydi, chunki bir xil hisoblashlarni bir necha bor takrorlashning oldi olinadi. 2. Dinamik dasturlash (Dynamic Programming) Dinamik dasturlash — bu memoizatsiyaning kengaytirilgan shakli bo‘lib, murakkab rekursiv muammolarni yechishda takrorlanadigan subproblemlarni hal qilishni optimallashtirishga qaratilgan. Bu usulda masalani kichik bo‘laklarga bo‘lish va har bir bo‘lakni alohida hal qilish orqali natijalarni saqlab borish mumkin. Dinamik dasturlash yordamida, algoritmning ishlash vaqtini sezilarli darajada tezlashtirish mumkin. 3. Tail Recursion (Tayl Rekursiya) Tayl rekursiya — rekursiyaning maxsus turi bo‘lib, bunda rekursiv chaqiruv oxirgi amaldan keyin (ya'ni, funksiya bajarilishni tugatgandan so‘ng) bajariladi. Bu, kompyuterning stek xotirasini samarali ishlatish imkonini beradi, chunki ba'zi til va kompilyatorlar tayl rekursiyani optimallashtirib, uni iterativ shaklga o‘zgartirishi mumkin. Shunda rekursiya stekda yangi joy ochishni talab qilmaydi va xotira sarfini kamaytiradi. 4. Binar yoki ikkilik kesish (Binary Splitting) Ba’zi rekursiv algoritmlar ko‘p marta bir xil hisoblashni amalga oshirishi mumkin. Binar kesish usulida masalani ikki qismga bo‘lish orqali hisoblashni optimallashtirish mumkin. Bu usul ko‘pincha rekursiv algoritimlarni takrorlashlardan saqlaydi va hisoblashlarni samarali tarzda amalga oshiradi. 5. Yodda saqlash (Caching) Yodda saqlash — bu memoizatsiyaning bir shakli bo‘lib, funksiyalar tomonidan qaytarilgan natijalarni saqlab, keyinchalik ularni chaqirishni ta’minlaydi. Odatda yodda saqlash ma'lumotlarni tezroq olish imkonini beradi va shu bilan algoritmning samaradorligini oshiradi. 6. Iterativ yondashuvga o‘zgartirish Ba'zi rekursiv algoritmlar iterativ shaklga o‘zgartirilishi mumkin. Agar rekursiya juda chuqur yoki ko‘p resurslarni talab qiladigan bo‘lsa, uni iteratsiya yordamida almashtirish mumkin. Iteratsiya stekni ishlatmasligi sababli xotira sarfini kamaytiradi va ko‘pincha samaraliroq bo‘ladi. 7. Rekursiv bo‘laklarni ketma-ket emas, balki parallel ravishda bajarish Agar rekursiv funksiya bir nechta mustaqil bo‘lakni hisoblab chiqayotgan bo‘lsa, ularni parallel ravishda bajarish mumkin. Bu parallel hisoblash resurslaridan foydalanishga yordam beradi va shu orqali ishlash vaqtini tezlashtiradi. Rekursiyani optimallashtirish, asosan, ishlash tezligini oshirish va xotira resurslarini samarali foydalanishni ta’minlashga qaratilgan. Har bir optimallashtirish usuli muayyan vaziyatlarga mos keladi va algoritmning qaysi jihatlari ko‘proq muammo tug‘dirishini hisobga olib tanlanadi. Bu jarayonni to‘g‘ri qo‘llash orqali rekursiv yondashuvlarning samaradorligini sezilarli darajada yaxshilash mumkin. Xulosa Rekursiya – bu kuchli vosita, lekin uni noto‘g‘ri ishlatish xatolarga va samarasizlikka olib kelishi mumkin. Rekursiyaning bazaviy holati va cheksiz chaqiruvlardan saqlanish tamoyillariga rioya qilish muhimdir. Dasturlashda rekursiv yechimlar ba’zan iteratsion yondashuvga qaraganda ancha sodda va tushunarli bo‘lsa-da, samaradorlik va xotira iste’moli nuqtai nazaridan ehtiyotkor bo‘lish talab etiladi. Amaliyotda rekursiyani muvaffaqiyatli qo‘llash uchun uning afzalliklari va cheklovlarini chuqur tushunish zarur. Shu bilan birga, optimallashtirish usullari (tail recursion, memoization) yordamida rekursiv algoritmlarning samaradorligini oshirish mumkin. Foydalanilgan adabiyotlar 1.Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein – Introduction to Algorithms. 2 .Robert Sedgewick, Kevin Wayne – Algorithms. 3. David Kopec – Classic Computer Science Problems in Python. 4. "GeeksforGeeks" va "Stack Overflow" – Onlayn dasturlash resurslari. 5. "Rekursiya haqida boshlang‘ich qo‘llanma" – mahalliy manbalar va darsliklar