COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython örnek paketi ↓

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ır

Recursion üç 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.

Python 3
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) == 24

KAVRADIĞ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

  1. Örneği değiştirmeden önce girdi sözleşmesini ve invariantı yaz.
  2. Uygun olan boş, sınır, tekrar ve adversarial girdileri ekle. Basit bir oracle ile karşılaştır.
  3. 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 ↗
İlerlemeden önce alıştırmayı çöz.