Veri yapılarını öğrenirken ilk olarak özyinelemeli, yani daha çok kullanılan ismiyle recursive fonksiyonlar öğretilir. Bunun sebebi, veri yapılarının diğer konularını öğrenirken özyinelemeli fonksiyonları sık sık görme ihtimaliniz çok yüksek. Dolayısıyla özyinelemeli fonksiyonları iyi anlamak veri yapılarının mantığını anlamak için çok önemlidir. Öncelikle özyinelemeli fonksiyonların ne olduğunu anlayarak başlayalım.
Özyinelemeli Fonksiyonlar (Recursive Functions) Nedir ?
Özyinelemeli fonksiyonlar, kendi kendine çağrılan fonksiyonlardır. Bu, bir fonksiyonun kendisini çağırarak işlemlerini tamamlaması anlamına gelir. Özyinelemeli fonksiyonların çalışma şekilleri, döngülerden farklıdır. Örneğin özyinelemeli fonksiyonlar, bir döngü içinde yaptıkları işlemleri tekrar etmek yerine, kendilerini tekrar çağırarak işlemlerini tamamlar.
Özyinelemeli fonksiyonların yararlarından bazıları şunlardır:
- Özyinelemeli fonksiyonlar, döngülerden daha okunaklı ve anlaşılması kolay olabilirler.
- Özyinelemeli fonksiyonlar, bazı problemleri daha kolay çözmeyi sağlar. Örneğin, bir arama ağacındaki tüm düğümleri gezmek için özyinelemeli fonksiyon kullanılabilir.
- Özyinelemeli fonksiyonlar, programlamada daha yüksek seviyeli kavramların anlaşılmasını sağlar. Özyinelemeli fonksiyonlar, programlama dilinde önceden tanımlanmış fonksiyonların ötesine geçerek, daha yüksek seviyeli kavramların anlaşılmasına yardımcı olur.
Ancak, özyinelemeli fonksiyonların yararlarının yanı sıra, bazı dezavantajları da vardır. Özyinelemeli fonksiyonlar, döngülerden daha yavaş çalışabilirler ve daha fazla bellek kullanırlar. Bu nedenle, özyinelemeli fonksiyonların kullanımı, problem çözme stratejisi olarak dikkatli bir şekilde seçilmelidir.
Şimdi bir örnek üzerinden görelim.
Özyinelemeli Fonksiyonlar (Recursive Functions) Örnekleri
Bu örneği c programlama dili ile yazacağız fakat sizler uygun syntax ile farklı dillerde de yazabilirsiniz.
#include <stdio.h>
int factorial(int n) {
if (n == 0) {
return 1;
}
else {
return n * factorial(n - 1);
}
}
int main(void) {
int number = 5;
int result = factorial(number);
printf("%d! = %d\n", number, result);
return 0;
}
Bu örnekte, ‘factorial’ adlı bir özyinelemeli fonksiyon tanımlanmıştır. Bu fonksiyon, verilen bir sayının faktöriyelini hesaplar. Fonksiyon, kendisini çağırarak işlemlerini tamamlar ve verilen sayının faktöriyelini hesaplar.
Örnekte, main fonksiyonu içinde ‘factorial’ fonksiyonu çağrılır ve sonuç ekrana yazdırılacaktır. Eğer çağrılan sayı 0 ise, fonksiyon 1 değerini döndürür. Eğer çağrılan sayı 0 değilse, fonksiyon kendisini çağırarak işlemlerini tamamlar. Bu şekilde, verilen sayının faktöriyeli hesaplanır.
Sonuç olarak, bu örnekte çağrılan sayı 5 ise, fonksiyon aşağıdaki şekilde çalışır:
factorial(5) = 5 * factorial(4) = 5 * (4 * factorial(3)) = 5 * (4 * (3 * factorial(2))) = 5 * (4 * (3 * (2 * factorial(1)))) = 5 * (4 * (3 * (2 * (1 * factorial(0))))) = 5 * (4 * (3 * (2 * (1 * 1)))) = 5 * 4 * 3 * 2 * 1 = 120
Bu nedenle, ‘factorial’ fonksiyonu 5 sayısının faktöriyelini döndürür ve ekrana “5! = 120” yazdırır.
Özyinelemeli Fonksiyon (Recursive Function) Bileşenleri
Base Case (Temel Durum): Recursive fonksiyonun çalışmasını durduracak bir durumdur. Bu durum, recursive fonksiyonun işlevini yerine getirirken dikkate alınır ve özel bir koşula ulaşıldığında fonksiyonun çalışması durdurulur.
Recursive Case (Yineleyici Durum): Recursive fonksiyonun kendisini tekrar çağırmasını sağlayacak bir durumdur. Bu durum, base case’e ulaşılmadığı sürece recursive fonksiyonun çalışmasını sürdürür.
Return Statement (Dönüş İfadesi): Recursive fonksiyonun, çalışması sonucunda döndüreceği değerdir. Bu değer, recursive fonksiyonun işlevini yerine getirirken özel bir koşula ulaşıldığında döndürülür.
Recursive Call (Yineleyici Çağrı): Recursive fonksiyonun kendisini tekrar çağırmasıdır. Bu çağrı, recursive case’de yapılır ve recursive fonksiyonun işlevini yerine getirirken base case’e ulaşılana kadar devam eder.
Özyinelemeli fonksiyon bileşenlerini anlamak için az önceki örnek üzerinden kısımlarının ne olduğunu yazalım. Fakat şimdide aynı dili Python dili yazalım.
def factorial(n):
# Base case (Temel durum): n = 1 ise
if n == 1:
return 1
# Recursive case (Yineleyici durum): n = 1 değilse
else:
# Recursive call (Yineleyici çağrı)
return n * factorial(n-1)
# Return statement (Dönüş İfadesi)
print(factorial(5))
Bu yazımızda veri yapılarının önemli bir konusu olan özyinelemeli yani recursive fonksiyonlar konusunu açıklamaya çalıştım. Diğer veri yapıları konularınıda incelemek isterseniz buradan tümüne ulaşabilirsiniz.