Soru tarihi
Rekürsiyon, ağaçların dolaşımı, faktöriyel hesaplama, hızlı sıralama gibi sorunları şık bir şekilde çözmek için sıkça kullanılan bir mekanizmadır. C dilinde rekürsif çağrılar doğrudan gerçekleştirilir, çünkü bir fonksiyon kendisini normal bir isim ile çağırabilir.
Problem
Rekürsiyon kullanışlıdır, ancak derin iç içe geçmişlik nedeniyle yığının hızlı bir şekilde dolup taşması riskini taşır (stack overflow). Ayrıca, büyük girdi verileri için optimizasyonlar olmadan etkisiz çalışır (örneğin, kuyruklu rekürsiyonun olmaması nedeniyle).
Çözüm
Rekürsiyonu uygulamadan önce maksimum olası derinliği kontrol etmek, temel durumları (base case) uygulamak, bellek (yığın) kullanımını dikkate almak ve kritik durumlarda algoritmayı iteratif bir versiyona yeniden yazmak gerekir.
Kod örneği:
// Rekürsif olarak faktöriyel bulma unsigned long factorial(unsigned int n) { if (n <= 1) return 1; // temel durum return n * factorial(n - 1); // rekürsif durum }
Anahtar özellikler:
C dilinde bir fonksiyon kendisini herhangi bir isimle doğrudan çağırabilir mi?
Hayır. Fonksiyon yalnızca kendi ismiyle kendisini çağırabilir ve bu isim çağrılmadan önce tanımlanmış olmalıdır (ya da en azından önceden bildirilmelidir).
Rekürsiyon her zaman döngüden daha mı etkilidir?
Hayır! İteratif çözümler genellikle daha hızlı ve daha güvenilir çalışır, çünkü yığını hızla harcamazlar ve fonksiyon çağrıları için ek maliyet gerektirmezler.
Rekürsiyondan sonra yığın başlangıç durumuna döner mi?
Evet, yığın, her rekürsif fonksiyondan çıkarken tamamen serbest bırakılır. En dıştaki fonksiyon tamamlandığında bellek eski durumuna döner.
Geliştirici, derinliği kontrol etmeden 100.000 düğümlü bir ağacı dolaşmak için bir fonksiyon gerçekleştirdi. Stack overflow ortaya çıktı.
Artıları:
Algoritma, rekürsiyon derinliğini izleyerek ve aşırı derinlikten koruma sağlayarak uygulanmıştır, büyük dolaşımlar partilere bölünmüştür (iteratif versiyonu).
Artıları: