šŸ” Arama Algoritmaları

šŸŽÆ Temel Problem

Arama nedir? Ƈok sayıda benzer nesne iƧinden belirli ƶzelliklere sahip olanları tespit etme işlemidir.

Günlük Hayattan Ɩrnekler

Problem Türü Pratik Kullanım
šŸ”¤ Pattern Matching Google’da kelime arama, metin editƶrlerinde “Bul” ƶzelliği
šŸ“Š Veri Tabanı Sorgusu Ɩğrenci bilgi sisteminde öğrenci bulma, envanter kontrolü

šŸ—ļø Temel Yapı Taşları

Element Sınıfı Tasarımı

class Element {
    int searchKey;        // Anahtar alan (ƶrn: 2019280045)
    String name;          // İsim
    String surname;       // Soyisim
    String department;    // Bölüm
}

Veri Koleksiyonu Oluşturma

final int MAXELEM = 1000;
Element[] database = new Element[MAXELEM];

šŸ“Œ Hedef: database[i].searchKey == arananAnahtar şartını sağlayan elemanı bulmak


šŸ“‚ Bƶlüm 1: Sırasız Koleksiyonda Arama

Yaklaşım

Hiçbir düzen olmadığında tek çare: baştan sona her şeyi kontrol et!

Ɩğrenci Listesi (Sırasız):
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  47823  │  Mehmet  │
│  12456  │  Ayşe    │
│  89012  │  Can     │ ← Aranan: 89012
│  34567  │  Zeynep  │
│  90123  │  Ali     │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

šŸ”§ Standart İmplementasyon

/**
 * Sırasız dizide basit doğrusal arama
 * @param db Arama yapılacak dizi
 * @param freeIdx İlk boş indeks (dolu eleman sayısı)
 * @param searchKey Aranan anahtar değer
 * @return Bulunan elemanın indeksi, bulunamazsa -1
 */
int search(Element[] db, int freeIdx, int searchKey) {
    int index = 0;
    
    // Her elemanı kontrol et
    while ((index < freeIdx) && (db[index].key != searchKey))
        index++;
    
    // Sonuna geldik ama bulamadık
    if (index == freeIdx)
        return -1;
    
    return index;  // Bulundu!
}

šŸ“ˆ Performans İncelemesi

Problem Boyutu: n = veri koleksiyonundaki eleman sayısı
Varsayım: Tüm elemanlar eşit sıklıkta aranır

Senaryo 1 - En Kötü Durum:
[1][2][3][4][5]...[998][999][1000]
                              ↑
                    Aranan burada veya yok
                    Toplam: 1000 karşılaştırma
Senaryo 2 - Ortalama Durum:
[1][2][3]...[497][498][499][500]...[1000]
                       ↑
              Ortalama burada bulunur
              Toplam: ~500 karşılaştırma
Durum Karşılaştırma Açıklama
šŸ”“ Worst Case n Eleman sonunda veya hiƧ yok
🟔 Average Case n/2 İstatistiksel ortalama

⚔ Optimizasyon: Bekçi Yöntemi (Sentinel)

Ana Fikir: Dizinin sonuna arama değerini kopyala → dƶngü kontrolü daha basit!

int search(Element[] db, int freeIdx, int searchKey) {
    int index = 0;
    
    // Bekçiyi yerleştir (her zaman bulacağımızı garanti eder)
    db[freeIdx].key = searchKey;
    
    // Artık sadece anahtar kontrolü yeterli
    while (db[index].key != searchKey)
        index++;
    
    // BekƧide mi bulduk? (yani gerƧekte yok)
    if (index == freeIdx)
        return -1;
    
    return index;
}

šŸŽÆ Avantaj: Dƶngüde 2 koşul yerine 1 koşul → %30-40 daha hızlı!

Normal:          while (i < n && arr[i] != key)
BekƧi ile:       while (arr[i] != key)
                 (Ƈok daha basit!)

šŸ“Š Bƶlüm 2: Sıralı Koleksiyonda Doğrusal Arama

Yeni Avantaj: Erken Ƈıkış!

Dizi sıralıysa ve aranan değerden büyük bir sayıya denk geldiysek → durabilirz!

Sıralı Dizi: [3, 7, 12, 18, 25, 34, 41, 56]
Aranan: 20

Adım 1: 3  < 20 āœ“ devam
Adım 2: 7  < 20 āœ“ devam
Adım 3: 12 < 20 āœ“ devam
Adım 4: 18 < 20 āœ“ devam
Adım 5: 25 > 20 āœ— DUR! (20 burada olamaz)
         ↑
    Burada durabiliyoruz!

šŸ’” Performans Kazancı

Senaryo Sırasız Sıralı KazanƧ
Var olan eleman n/2 n/2 Aynı
Olmayan eleman n n/2 %50 daha hızlı!

Neden? Çünkü olmayan elemanı aramaya başlangıƧta, ortada veya sonda olabilir:

  • Sırasız → Her zaman sonuna kadar bakmalıyız
  • Sıralı → Ortalama ortada durabiliyoruz

šŸš€ Bƶlüm 3: Binary Search (İkili Arama)

🧠 Temel Mantık: Sürekli Ortadan Böl!

Divide and Conquer Prensibi:

  1. Problemi küçük parçalara böl
  2. Her bƶlmede problem boyutu yarıya iner
  3. Logaritmik hız kazancı sağla

šŸ“– Telefon Rehberi Ɩrneği

"Yılmaz" arıyorsunuz:

1. Rehberi ortadan aƧın → "M" harfi
   → Yılmaz > M → Sağ yarıya bak

2. Sağ yarıyı ortadan aƧın → "S" harfi
   → Yılmaz > S → Tekrar sağa

3. O yarıyı ortadan aƧın → "Y" harfi
   → Bulundu! āœ“

3 adımda 1000 isim arasından buldunuz!

šŸ”¢ Algoritma Adımları

Başlangıç:
[2][5][9][12][15][19][23][27][31][35]
 ↑                              ↑
left=0                      right=9

Aranan: 23

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Adım 1:
middle = (0+9)/2 = 4
[2][5][9][12][15][19][23][27][31][35]
            ↑
        15 < 23 → SAĞ YARIDA ARA
        
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Adım 2:
left=5, right=9
middle = (5+9)/2 = 7
[19][23][27][31][35]
        ↑
    27 > 23 → SOL YARIDA ARA
    
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Adım 3:
left=5, right=6
middle = (5+6)/2 = 5
[19][23]
    ↑
23 == 23 → BULUNDU! āœ…

šŸ’» Kod İmplementasyonu

/**
 * Sıralı dizide ikili arama
 * @param db Sıralı dizi
 * @param freeIdx İlk boş indeks
 * @param searchKey Aranan değer
 * @return Bulunan indeks veya -1
 */
int searchBin(Element[] db, int freeIdx, int searchKey) {
    int left = 0;
    int right = freeIdx - 1;
    int middle = (left + right) / 2;
    
    // Sol ve sağ çakışana kadar devam
    while ((left < right) && (db[middle].key != searchKey)) {
        
        if (searchKey < db[middle].key)
            right = middle - 1;  // Sol yarıda ara
        else
            left = middle + 1;   // Sağ yarıda ara
        
        // Yeni orta noktayı hesapla
        middle = (left + right) / 2;
    }
    
    // Kontrol: GerƧekten bulduk mu?
    if (db[middle].key == searchKey)
        return middle;
    
    return -1;  // Bulunamadı
}

šŸ“Š Performans Analizi

Matematiksel Kanıt:

  • Her adımda problem boyutu: n → n/2 → n/4 → n/8 → …
  • k adım sonra: n / 2^k = 1
  • Ƈƶzüm: k = logā‚‚(n)
Eleman Sayısı vs İşlem Sayısı:

n = 10       → logā‚‚(10)  ā‰ˆ 3-4 adım
n = 100      → logā‚‚(100) ā‰ˆ 6-7 adım
n = 1,000    → logā‚‚(1000) ā‰ˆ 10 adım
n = 1,000,000 → logā‚‚(1M) ā‰ˆ 20 adım (!!)

šŸŽÆ SonuƧ: Hem worst case hem average case O(log n)

šŸ†š Doğrusal vs İkili Arama

1 milyon elemanlı dizide arama:

Doğrusal Arama:
ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ 500,000 işlem

İkili Arama:
ā–ˆ 20 işlem

šŸš€ 25,000 kat daha hızlı!

šŸŽÆ Bƶlüm 4: İnterpolasyon Araması

šŸ’” Akıllı Tahmin Yƶntemi

İkili arama: Her zaman tam ortaya bakar
İnterpolasyon: Değere göre akıllıca tahmin eder

šŸ“ Formül Farkı

// İKİLİ ARAMA - Basit ortalama
middle = left + 0.5 * (right - left);

// İNTERPOLASYON - Oransal tahmin
estimate = (key - a[left].key) / (a[right].key - a[left].key);
middle = left + estimate * (right - left);

šŸŽ² Ƈalışma Prensibi

Dizi: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Aranan: 85

İkili Arama:
middle = (0 + 9) / 2 = 4
→ 50'ye bakar (Ƨok geride!)

İnterpolasyon:
estimate = (85 - 10) / (100 - 10) = 0.833
middle = 0 + 0.833 * 9 ā‰ˆ 7
→ 80'e bakar (Ƨok yakın!)

āœ… Ne Zaman Kullanılır?

Uygun: Anahtarlar yaklaşık eşit aralıklarla dağılmış

İyi Ɩrnek (Eşit Dağılım):
[100, 200, 300, 400, 500, 600, 700, 800]
  ↑    ↑    ↑    ↑    ↑    ↑    ↑    ↑
  100'er 100'er artıyor - TAHMİN ƇALIŞIR āœ“

Uygunsuz: Düzensiz dağılım

Kƶtü Ɩrnek (Düzensiz):
[1, 2, 3, 4, 5, 999, 1000, 1001, 1002]
 ↑  ↑  ↑  ↑  ↑  ↑↑↑   Büyük sıƧrama!
 TAHMİN YANILIR āœ—

šŸ“‹ Genel Karşılaştırma Tablosu

Algoritma Ɩn Koşul Worst Case Average Case Uygun Veri Boyutu
Doğrusal (Sırasız) Yok O(n) O(n/2) n < 100
Doğrusal (Sıralı) Sıralı O(n) O(n/2)* n < 100
İkili Arama Sıralı O(log n) O(log n) n > 100 āœ…
İnterpolasyon Sıralı + Eşit Dağılım O(n) O(log log n) Ƈok büyük + uniform

*Sıralı dizide bulunamayan elemanlar iƧin daha iyi


šŸŽ“ Pratik Kullanım Kılavuzu

Karar Verme Şeması

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Verin sıralı mı?            │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
           │
    ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”
    │ HAYIR       │ EVET
    ā–¼             ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│Doğrusal │  │ Eleman sayısı?   │
│ Arama   │  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜           │
                ā”Œā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”
            < 100         > 100
                │             │
                ā–¼             ā–¼
           ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
           │Doğrusal │  │Veriler düzenli│
           │         │  │dağılmış mı?   │
           ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                              │
                        ā”Œā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”
                    HAYIR        EVET
                        │           │
                        ā–¼           ā–¼
                  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
                  │İkili    │ │İnterpolasyon │
                  │Arama āœ… │ │Araması       │
                  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

šŸ’¼ GerƧek Dünya Ɩrnekleri

Senaryo Ɩnerilen Algoritma Neden?
šŸ“± Telefon rehberi İkili Arama Sıralı + büyük veri
šŸ“š Kütüphane kataloğu İkili Arama Alfabetik sıra
šŸŽ® Oyun skorları (sırasız) Doğrusal Küçük + sırasız
šŸ“Š Hisse senedi fiyatları İnterpolasyon Zamana gƶre düzenli
šŸ”¢ Sıralı numaralar İnterpolasyon Eşit aralıklı

šŸ”‘ Anahtar Kavramlar Sƶzlüğü

Terim Almanca AƧıklama
Search Key Suchschlüssel Aranacak benzersiz değer (örn: TC no)
Sentinel Markieren Döngüyü basitleştiren yardımcı değer
Divide & Conquer Teile-und-Herrsche Problemi bƶlerek Ƨƶzme stratejisi
Time Complexity Laufzeit Algoritmanın hız performansı
Binary Search BinƤre Suche Yarılayarak arama
Interpolation Interpolationssuche Oransal tahminle arama

šŸŽÆ Ɩnemli Hatırlatmalar

āš ļø Binary Search İƧin Kritik Noktalar

  1. Dizi mutlaka sıralı olmalı!
  2. Middle hesabında overflow riski: (left + right) / 2 yerine left + (right - left) / 2
  3. Boundary koşullarına dikkat: left <= right mı left < right mi?

šŸ”§ BekƧi Tekniği İpuƧları

// āš ļø Dikkat: BekƧi iƧin bir boş alan gerekli!
Element[] database = new Element[MAXELEM + 1];  // +1 ƶnemli!

šŸ“ˆ Büyük-O Notasyonu Hatırlatma

O(1)        - Sabit zaman (en hızlı)
O(log n)    - Logaritmik (Ƨok hızlı)
O(n)        - Doğrusal (normal)
O(n log n)  - Linearitmik (yavaş)
O(n²)       - Karesel (çok yavaş)