Biz artıq bilirik ki, bir funksiya öz daxilində başqa funksiyanı çağıra bilər. Amma bilməmiz gərəkən daha bir şey var: funksiya özü özünü də çağıra bilər. Proqramlaşdırmada funksiyaların özü özünü çağırmasına rekursiya, bu cür funksiyalara da rekursiv funksiyalar deyilir.
Gəlin verilmiş ədədin faktoriyalını (n!) hesablayan kiçik bir funksiya hazırlayaq. Riyaziyyatdan da bildiyiniz kimi n ədədinin faktorialı 1-dən n-ə qədər (daxil olmaqla) natural ədədlərin hasilinə bərabərdir. Məsələn, 5!=5*4*3*2*1. Və o da məlumdur ki, 1!=1 və 0!=1. Buradan belə bir məntiq yürütmək olur ki, n! hesablamaq üçün n*(n-1)! hesablamalıyıq, yəni 5!=5*4!. Belə olan halda 4! üçün 4*3!, 3! üçün 3*2!, 2! hesablamaq üçün də 2*1! hesablanmalıdır. 1! isə 1-ə bərabər olduğuna görə rekursiya burada bitmiş olur.
O zaman rekursiv funksiya aşağıdakı kimi olacaq:
>>> def fakt(n): if n<=1: return 1 else: return n*fakt(n-1) >>> fakt(5) 120 >>>
Rekursiv funksiyalardan istifadə edərkən diqqət etmək lazımdır ki, sonsuz rekursiya alınmasın. Adətən sonsuz rekursiyalara gətirib çıxaran aşağıdakı iki səbəb olur:
- Rekursiyadan çıxışın düzgün təşkil edilməməsi. Məsələn, yuxarıdakı faktorial funksiyasında if n<=1 şərti verilməsəydi, rekursiya mənfi ədədlərə doğru sonsuz şəkildə davam edərdi.
- Rekursiv çağırışda parametrlərin düzgün verilməməsi. Məsələn, əgər fakt(n) funksiyası fakt(n-1) əvəzinə elə fakt(n) funksiyasını çağırsaydı, yenə də sonsuz rekursiya alınardı.
Gəlin daha bir misal işləyək. Verilmiş a ədədini n qüvvətinə yüksəldən funksiya təyin edək:
>>> def power(a,n): if n==1: return a else: return a*power(a,n-1) >>> power(2,4) 16 >>> power(8,3) 512 >>>
Biz ən başda qeyd etdik ki, rekursiv funksiyalar özü özünə müraciət edən funksiyalardır. Amma bu müraciətlərin sayı (rekursiyanın dərinliyi) sonsuz ola bilməz. Hətta səhvən sonsuz rekursiya təşkil etsək belə praktiki olaraq funksiya sonsuz sayda icra olunmayacaq. Rekursiyanın dərinliyi ilə bağlı aşağıdakıları bilmək vacibdir:
- Rekursiyanın dərinliyinə məhdudiyyət qoyulmuşdur. Default olaraq (susmaya görə) rekursiv funksiya 1000 dəfə özü özünə müraciət edə bilər.
- Bu məhdudiyyət sys.setrecursionlimit() funksiyasından istifadə edilməklə dəyişdirilə bilər. Cari limitə baxmaq üçün isə sys.getrecursionlimit() funksiyası çağırılmalıdır.
- Buna baxmayaraq rekursiyanın dərinliyi əməliyyat sistemi tərəfindən təyin olunan stekin ölçüsü ilə məhdudlaşdırılır.
Son olaraq onu da deyək ki, rekursiv funksiyalar ümumilikdə proqramın məhsuldarlığını azaltdığı üçün onlara yalnız zərurət halında müraciət etmək lazımdır.