Özyineleme

Bilgisayar ve Programlamaya Giriş
Temel durumÇağrıYığınVerimlilikBellekleme
Sercan KÜLCÜ · Giresun Üniversitesi

Giriş

Öğrenme Çıktıları

Yapı

Temel durum ve özyinelemeli adımı belirlemek.

İzleme

Çağrı yığınını adım adım takip etmek.

Karşılaştırma

Özyineleme ile döngüyü değerlendirmek.

İyileştirme

Tekrarlı hesaplamayı memoization ile azaltmak.

Temeller

Özyineleme Nedir?

  • Bir metodun problemi daha küçük örneğe indirerek kendisini çağırmasıdır.
  • Her çağrı kendi parametre ve yerel değişkenleriyle ayrı yığın çerçevesi oluşturur.
  • Problem temel duruma doğru ilerlemiyorsa çağrılar sonlanmaz.

Temeller

İki Zorunlu Parça

Temel durum

Sonucun doğrudan bilindiği ve yeni çağrı yapılmayan durum.

Özyinelemeli adım

Problemi daha küçük veya daha basit örneğe dönüştüren çağrı.

Örnekler

Özyinelemeli Faktöriyel

static long faktöriyel(int n) {
    if (n < 0) throw new IllegalArgumentException();
    if (n <= 1) return 1;
    return n * faktöriyel(n - 1);
}
  • Temel durum n ≤ 1'dir.
  • Her çağrıda n bir azalır.

Çağrı Yığını

faktöriyel(4) Çağrıları

f(4)
4 × f(3)
4 × 3 × f(2)
4 × 3 × 2 × f(1)
24
  • Çağrılar temel duruma ulaşıncaya kadar yığında açılır.
  • f(1) değeri döndükten sonra çarpımlar ters sırada tamamlanır.

Örnekler

1’den n’e Toplam

static int toplam(int n) {
    if (n <= 0) return 0;
    return n + toplam(n - 1);
}
  • Tanım: toplam(n) = n + toplam(n-1).
  • Temel değer: toplam(0) = 0.

Örnekler

Rakamlar Toplamı

static int rakamToplamı(int n) {
    n = Math.abs(n);
    if (n < 10) return n;
    return n % 10 + rakamToplamı(n / 10);
}

Örnekler

Palindrom Kontrolü

static boolean palindrom(String s, int sol, int sağ) {
    if (sol >= sağ) return true;
    if (s.charAt(sol) != s.charAt(sağ)) return false;
    return palindrom(s, sol + 1, sağ - 1);
}
  • Her çağrı iki uçtan birer karakter çıkarır.
  • Ortada sıfır veya bir karakter kaldığında sonuç true'dur.

Örnekler

Öklid ile EBOB

static int ebob(int a, int b) {
    if (b == 0) return Math.abs(a);
    return ebob(b, a % b);
}
  • Kalanlar küçülerek 0'a ulaşır.
  • Son sıfır olmayan kalan EBOB'dur.

Çağrı Yığını

Çağrı Yığını

  • Yeni çağrı yapıldığında mevcut metodun dönüş noktası saklanır.
  • Temel durumdan sonra çağrılar ters sırada tamamlanır.
  • Çok derin özyineleme StackOverflowError oluşturabilir.

Verimlilik

Özyineleme mi Döngü mü?

  • Doğal olarak kendine benzeyen ağaç ve böl-parçala problemlerinde özyineleme açık olabilir.
  • Basit doğrusal tekrarlar döngüyle daha az yığın belleği kullanır.
  • Seçim yalnızca kod kısalığına değil doğruluk, okunabilirlik ve kaynak kullanımına dayanmalıdır.

Verimlilik

Faktöriyel Karşılaştırması

ÖzellikÖzyinelemeliDöngülü
ZamanO(n)O(n)
Ek yığınO(n)O(1)
AkışTanıma yakınAçık sayaç
Derinlik riskiVarYok

Verimlilik

Fibonacci Sorunu

  • Doğrudan özyinelemeli tanım aynı alt sonuçları tekrar tekrar hesaplar.
  • fibonacci(n-1) ve fibonacci(n-2) çağrı ağaçları büyük ölçüde örtüşür.
  • Bu yaklaşımın çalışma süresi yaklaşık üstel büyür.

Verimlilik

Doğrudan Fibonacci

static long fib(int n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}
  • Tanımı doğrudan yansıtır fakat büyük n için verimsizdir.

İyileştirme

Memoization

  • Hesaplanan alt problem sonuçlarını önbellekte saklar.
  • Aynı girdi tekrar geldiğinde yeni çağrı ağacı yerine kayıtlı değer döner.
  • Zaman kazanımı karşılığında ek bellek kullanılır.

İyileştirme

Belleklemeli Fibonacci

static long fib(int n, long[] bellek) {
    if (n <= 1) return n;
    if (bellek[n] != 0) return bellek[n];
    bellek[n] = fib(n-1, bellek) + fib(n-2, bellek);
    return bellek[n];
}
  • Toplam zaman O(n), ek alan O(n) olur.

İyileştirme

Kuyruk Özyinelemesi

  • Özyinelemeli çağrı metodun son işlemidir.
  • Bazı diller kuyruk çağrılarını yığın büyütmeden optimize eder.
  • Java dili/JVM genel olarak kuyruk çağrısı optimizasyonunu garanti etmez.

Doğrulama

Hata Ayıklama

  • Temel durumun ulaşılabilir olduğunu kanıtlayın.
  • Her çağrıda problemin hangi ölçüye göre küçüldüğünü yazın.
  • Küçük girdi için çağrı ve dönüş sırasını tabloya dökün.
  • Yığın derinliği ve tekrarlı alt problemleri değerlendirin.

Özet

Bölüm Özeti

  • Özyineleme temel durum ve küçülen özyinelemeli adımdan oluşur.
  • Çağrılar yığında birikir ve temel durumdan sonra ters sırada döner.
  • Doğrusal tekrarlar çoğu zaman döngüyle daha az bellek kullanır.
  • Memoization tekrarlanan alt problem sonuçlarını saklayarak zamanı azaltır.

Özet

Kontrol Soruları

  1. Temel durum olmazsa ne olur?
  2. Çağrı yığını neden ters sırada çözülür?
  3. Özyinelemeli faktöriyel ne kadar ek yığın kullanır?
  4. Doğrudan Fibonacci neden yavaştır?
  5. Java'da kuyruk özyinelemesi neden yığın güvenliği sağlamaz?

Son

Özyineleme
1 / 1Sercan KÜLCÜ, Tüm hakları saklıdır.

← → veya boşluk ile gezinin · F: tam ekran · Home/End: ilk/son slayt