š 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:
- Problemi küçük parçalara böl
- Her bƶlmede problem boyutu yarıya iner
- 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
- Dizi mutlaka sıralı olmalı!
- Middle hesabında overflow riski:
(left + right) / 2yerineleft + (right - left) / 2 - Boundary koÅullarına dikkat:
left <= rightmıleft < rightmi?
š§ 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Å)