Bellek ve özyineleme · 07 / 53
Recursion, çağrı ağacı ve explicit stack
Anla → iz sür → uygula → gerekçelendir
2 dk okuma · uygulama için ayrıca zaman ayırRecursion üç karar ister: base case, küçülen alt problem ve sonuçları birleştirme. Faktöriyel n!=n·(n−1)! ilişkisiyle yazılır; n=0 için 1 dönmek sınır koşuludur. Negatif girdiyi reddetmezsen küçülme base case'e ulaşmayabilir. Her aktif çağrı çerçevesi alan tüketir; tail recursion'ın otomatik optimize edildiğini Python'da varsayma.
Naif Fibonacci aynı alt problemleri tekrar tekrar çözer: fib(5) hem fib(4) hem fib(3) çağırır, fib(4) tekrar fib(3) hesaplar. Bu çağrı ağacı ile stack derinliği aynı değildir: iş sayısı üstel olabilirken en derin aktif zincir O(n)'dir. Memoization tekrarları kaldırır; iteratif çözüm çağrı stack'ini de kaldırabilir.
Ağaç DFS'sinde recursion okunaklıdır fakat çok uzun zincir stack sınırına ulaşır. Explicit stack, “şimdi işlenecek düğüm” ve gerekirse “geri dönünce yapılacak iş” durumlarını saklar. Preorder, inorder, postorder farkı fonksiyonda düğümü ne zaman işlediğindir. Algoritmanın doğruluğunu sadece recursion kullanmasına bağlama; indüksiyonla alt problem sözleşmesini göster.
Adım adım iz sürme
fact(4) → fact(3) → fact(2) → fact(1) → fact(0). Dönüşte 1,1,2,6,24 hesaplanır; toplam 5 aktif çerçeve.
Maliyet ve varsayımlar
Faktöriyel unit-cost varsayımıyla O(n) işlem, recursive O(n) stack. Büyük tam sayı çarpma maliyeti ayrıca büyür.
Çalıştırılabilir örnek
Python 3 ile çalıştır. Assert küçük bir örneği denetler; genel doğruluk ispatı değildir. Bazı ileri örnekler özellikle küçük model veya referans oracle'dır; tam üretim uygulaması değildir.
def factorial(n):
if n < 0:
raise ValueError("negative factorial")
result = 1
for x in range(2, n + 1):
result *= x
return result
assert factorial(4) == 24KAVRADIĞINI KONTROL ET
Sıra sende
Bir milyon düğümlü zincirde recursive DFS yerine ne kullanırsın?
Çözümün mantığını göster
Explicit stack ve visited kümesi; recursion limitini yükseltmek güvenilir çözüm değildir. Yol durumu gerekiyorsa çerçevede iterator/index tut.
Bir adım ileri
- Örneği değiştirmeden önce girdi sözleşmesini ve invariantı yaz.
- Uygun olan boş, sınır, tekrar ve adversarial girdileri ekle. Basit bir oracle ile karşılaştır.
- Belirtilen modelde maliyeti çıkar; farklı girdi büyüklüklerini ölç ve farkları gerekçelendir.
Temel kaynaklar ve ders notları
Bu eğitimde özgün anlatım kullanıldı; aşağıdaki kaynaklar ispatlar ve ileri okumalar sunar. Bağlantılar daha geniş ders modülünü kapsayabilir.
MIT 6.006 · Introduction to Algorithms ↗