Bölüm 3: Arama Algoritmaları
Çoktan Seçmeli · Doğrusal Arama
Soru 1: Sırasız Veri
Sırasız bir dizide tek seferlik bir arama yapılacak. Bu bölümdeki algoritmalardan hangisi dizi sıralanmadan doğru sonuç verir?
D: Doğrusal arama her öğeye bakar; önkoşulu yoktur. İkili, atlayarak, üstel ve ara değer arama sıralı dizi ister: sırasız dizide hata vermez ama var olan öğeyi “yok” (−1) bulabilir.
Çıktı Sorusu · Doğrusal Arama
Soru 2: Kaç Karşılaştırma?
dizi = {33, 21, 12, 7, 8, 1, 3, 44, 56, 18} (n = 10) için dogrusalArama(dizi, 10, 44) ve dogrusalArama(dizi, 10, 17) ne döndürür? Her birinde dizi[i] != aranan kaç kez değerlendirilir?
int dogrusalArama(int[] dizi, int n, int aranan) { int i = 0; while (i < n && dizi[i] != aranan) i++; if (i < n) return i; else return -1; }
Cevabı göster
- 44: indis 7'de bulunur → 7 döner; i = 0 … 7 için 8 karşılaştırma.
- 17: dizide yok → −1; 10 karşılaştırma. i = 10 olunca
i < nyanlış olur ve kısa devre && sayesindedizi[10]'a erişilmez.
i < n testi de sayılırsa 44 için 8, 17 için 11 kez yapılır. Başarılı aramada ortalama (n + 1)/2 = 5,5 karşılaştırma.
Adım Adım Çalıştırma · Doğrusal Arama
Soru 3: Bekçili Arama
gozcuIleAra(dizi, 5, 7) çağrısı dizi = {12, 5, 9, 20, 7} için çalışıyor. Döngü nerede durur, metot ne döndürür?
Aranan 7, son öğe de 7. sonEleman = 7 saklanır, son hücreye bekçi olarak aranan (7) yazılır; dizi görünürde değişmez.
dizi[0] = 12 ≠ 7 → i = 1. Döngüde yalnızca bir karşılaştırma var; i < n testi yok.
dizi[1] = 5 ≠ 7 → i = 2.
dizi[2] = 9 ≠ 7 → i = 3.
dizi[3] = 20 ≠ 7 → i = 4.
dizi[4] = 7 (bekçi) → döngü durur. Son hücreye sonEleman geri yazılır.
i < n − 1 yanlış (4 < 4), ama sonEleman == aranan doğru → 4 döner. Bu ikinci koşul olmasaydı gerçek son öğe “bulunamadı” sayılırdı. 4 aransaydı aynı döngü i = 4'te durur ve −1 dönerdi.
int gozcuIleAra(int[] dizi, int n, int aranan) { int sonEleman = dizi[n - 1]; dizi[n - 1] = aranan; // bekçi int i = 0; while (dizi[i] != aranan) i++; dizi[n - 1] = sonEleman; // geri koy if (i < n - 1 || sonEleman == aranan) return i; return -1; }
Çoktan Seçmeli · Doğrusal Arama
Soru 4: Ortalama Başarılı Arama
10 öğeli bir dizide aranan her zaman vardır ve her konumda olma olasılığı eşittir. Doğrusal aramada ortalama kaç karşılaştırma yapılır?
B: i. konumdaki öğe i karşılaştırmayla bulunur, olasılık 1/n: Σ i/n = (n + 1)/2 = 11/2 = 5,5. 10 başarısız aramanın sayısıdır; 5 = n/2 yaklaşık değerdir. Ortalama da O(n)'dir.
Çıktı Sorusu · İkili Arama
Soru 5: Yazdırılan Orta Öğeler
Dizi [2, 3, 4, 7, 8, 9, 10, 21, 22, 31] iken aranan 40 olursa aşağıdaki kod ekrana ne yazdırır ve ne döndürür?
int baslangic = 0; int bitis = dizi.length - 1; while (baslangic <= bitis) { int orta = baslangic + (bitis - baslangic) / 2; System.out.println(dizi[orta]); if (dizi[orta] == aranan) { return orta; } else if (dizi[orta] > aranan) { bitis = orta - 1; } else { baslangic = orta + 1; } } return -1;
Cevabı göster
Çıktı: 8 21 22 31, dönüş −1.
| baslangic | bitis | orta | dizi[orta] |
|---|---|---|---|
| 0 | 9 | 4 | 8 |
| 5 | 9 | 7 | 21 |
| 8 | 9 | 8 | 22 |
| 9 | 9 | 9 | 31 |
40 tüm öğelerden büyük olduğu için her turda sağa gidilir; baslangic = 10 > bitis = 9 olunca döngü biter. 4 tur = ⌊log₂ 10⌋ + 1 (en kötü durum).
Adım Adım Çalıştırma · İkili Arama
Soru 6: 17 Öğede İkili Arama
Önceki sorudaki kod [2, 3, 4, 7, 8, 9, 10, 21, 22, 31, 33, 37, 38, 39, 40, 42, 45] dizisinde 40'ı arıyor. Ekrana ne yazılır, hangi indis döner?
17 öğeli sıralı dizi, aranan 40. Arama aralığı [0, 16].
orta = 0 + (16 − 0) / 2 = 8; dizi[8] = 22 yazdırılır.
22 < 40 → baslangic = 9; sol yarı elenir.
orta = 9 + (16 − 9) / 2 = 12; dizi[12] = 38 yazdırılır.
38 < 40 → baslangic = 13; sol yarı elenir.
orta = 13 + (16 − 13) / 2 = 14; dizi[14] = 40 yazdırılır.
dizi[14] == 40 → return 14. Çıktı 22, 38, 40: 17 öğede 3 tur (en fazla ⌊log₂ 17⌋ + 1 = 5).
int baslangic = 0; int bitis = dizi.length - 1; while (baslangic <= bitis) { int orta = baslangic + (bitis - baslangic) / 2; System.out.println(dizi[orta]); if (dizi[orta] == aranan) { return orta; } else if (dizi[orta] > aranan) { bitis = orta - 1; } else { baslangic = orta + 1; } }
Çoktan Seçmeli · İkili Arama
Soru 7: İkili Aramanın Önkoşulu
İkili aramanın doğru çalışması için gereken koşul hangisidir?
B: Orta öğeye bakıp yarıyı elemek ancak sıralı dizide doğrudur; indisle sabit zamanda erişim de gerekir (bağlı listede orta O(n)). Tekrarlı öğeler sorun değildir: eşleşenlerden biri bulunur (ilk konum gerekiyorsa küçük bir değişiklik yapılır). D, ara değer aramanın varsayımıdır.
Çoktan Seçmeli · İkili Arama
Soru 8: İki Milyon Öğe
Sıralı 2.000.000 öğeli bir dizide ikili arama en kötü durumda kaç tur (orta karşılaştırması) yapar?
C: En fazla ⌊log₂ n⌋ + 1 tur: 2²⁰ = 1.048.576 ≤ 2.000.000 < 2²¹ → ⌊log₂ n⌋ = 20 → 21 tur. 20, ⌊log₂ n⌋'deki “+ 1” unutulunca çıkar; 1.000.000 doğrusal aramanın ortalamasıdır.
Çoktan Seçmeli · İkili Arama
Soru 9: Orta İndiste Taşma
Çok büyük dizilerde int orta = (bas + son) / 2; satırı neden hatalıdır ve güvenli yazımı hangisidir?
A: İki büyük indisin toplamı int sınırını aşar ve negatif bir orta, dizi dışı erişime yol açar. bas + (son - bas) / 2 ya da (bas + son) >>> 1 taşmaz. D taşmış değerin mutlak değerini alır; yine yanlıştır.
Çoktan Seçmeli · İkili Arama
Soru 10: ±1 Unutulursa
İkili aramada son = orta - 1; yerine son = orta; yazılırsa (döngü koşulu bas <= son) ne olabilir?
C: bas = son = orta iken aranan dizi[orta]'dan küçükse son = orta olur ve aralık hiç değişmez; döngü sonsuza dek döner. Orta öğe zaten denetlendiği için sınırlar ±1 ile güncellenmelidir.
Çıktı Sorusu · İkili Arama
Soru 11: Arrays.binarySearch
int[] a = {2, 5, 8, 12, 16}; için aşağıdaki satırlar ne yazdırır?
System.out.println(Arrays.binarySearch(a, 9)); System.out.println(Arrays.binarySearch(a, 16)); System.out.println(Arrays.binarySearch(a, 1)); System.out.println(Arrays.binarySearch(a, 20));
Cevabı göster
-4 4 -1 -6
- 9 yok; ekleme noktası 3 (8 ile 12 arası) → −3 − 1 = −4.
- 16 indis 4'te → 4.
- 1 yok; ekleme noktası 0 → −1. 20 yok; ekleme noktası 5 (sona) → −6.
Bulunamayınca −(ekleme noktası) − 1 döndürülür; böylece dönüş değeri hiçbir zaman “bulundu” ile karışmaz (ekleme noktası 0 iken bile −1).
Klasik Soru · İkili Arama
Soru 12: Örtük Arama Ağacı
[4, 9, 13, 20, 26, 31, 40] dizisinde ikili aramanın karşılaştırma ağacını çizin. Hangi öğeler 1, 2 ve 3 karşılaştırmada bulunur? Başarılı aramalarda ortalama kaç karşılaştırma yapılır?
Cevabı göster
Kök ilk orta öğedir (20); sol yarının ortası 9, sağ yarınınki 31; kalanlar yapraktır:
- 1 karşılaştırma: 20 · 2 karşılaştırma: 9, 31 · 3 karşılaştırma: 4, 13, 26, 40
Ortalama (1 + 2·2 + 4·3)/7 = 17/7 = 2,43. Ağacın derinliği ⌊log₂ 7⌋ + 1 = 3: en kötü durum. Ağaç bellekte kurulmaz; orta hesabı onu örtük olarak gezer.
Çoktan Seçmeli · İkili Arama
Soru 13: İlk Konumu Bulmak
Tekrarlı öğeler içeren sıralı dizide aranan değerin ilk konumunu bulmak için eşitlik durumunda (dizi[orta] == aranan) ne yapılmalıdır?
D: Eşleşme kaydedilir ve daha soldaki bir eşleşme için sol yarıda aranır; döngü bitince sonuc döner. Süre O(log n) kalır. C de doğru sonucu verir ama tüm öğeler eşitse O(n)'e çıkar; A herhangi bir eşleşmeyi verir, B son konuma gider.
Çıktı Sorusu · Hash ile Arama
Soru 14: Karakter Toplamı Hash'i
Sunumdaki hashFonksiyonu m = 10 ile "kar", "ark" ve "kara" anahtarları için hangi kovaları verir? (Unicode: a = 97, k = 107, r = 114)
int hashFonksiyonu(String anahtar, int m) { int toplam = 0; for (char k : anahtar.toCharArray()) toplam += k; return toplam % m; }
Cevabı göster
- "kar": 107 + 97 + 114 = 318 → 8
- "ark": 97 + 114 + 107 = 318 → 8 (çakışma)
- "kara": 318 + 97 = 415 → 5
Toplam harflerin sırasını görmez: aynı harflerden oluşan kelimeler her zaman çakışır. Java'nın String.hashCode()'u konuma bağlı ağırlık (Σ s[i] · 31ⁿ⁻¹⁻ⁱ) kullanarak bu sorunu azaltır.
Adım Adım Çalıştırma · Hash ile Arama
Soru 15: Doğrusal Yoklama ile Ekleme
Boş tabloya (m = 10) 23, 43, 13, 27, 37 sırayla hashEkle ile ekleniyor. Her anahtar hangi kovaya yerleşir? Ardından 33 aranırsa kaç kova yoklanır?
Boş tablo, m = 10, h(x) = x % 10. Sırayla 23, 43, 13, 27, 37 eklenecek; dolu kovada bir sonrakine geçilir (doğrusal yoklama).
h(23) = 3: kova boş → 23 buraya yerleşir.
h(43) = 3 dolu → 4 yoklanır; ilk boş kova 4. (2 yoklama)
h(13) = 3 dolu → 4, 5 yoklanır; ilk boş kova 5. (3 yoklama)
h(27) = 7: kova boş → 27 buraya yerleşir.
h(37) = 7 dolu → 8 yoklanır; ilk boş kova 8. (2 yoklama)
hashArama(33): h = 3 → 23, 43, 13 ile karşılaştırılır, kova 6 boş → −1. 4 kova yoklandı: 3, 4, 5 kovaları bitişik bir küme (birincil kümelenme) oluşturdu.
void hashEkle(Integer[] tablo, int anahtar) { int m = tablo.length; int indis = anahtar % m; while (tablo[indis] != null) indis = (indis + 1) % m; // sonraki tablo[indis] = anahtar; }
Çıktı Sorusu · Hash ile Arama
Soru 16: m = 7 Tablo
m = 7, h(x) = x % 7 ve doğrusal yoklama kullanan boş bir tabloya sırayla 15, 22, 8, 29, 6 ekleniyor. Son tablo nedir? 36 aranırken kaç kova yoklanır?
Cevabı göster
15 → 1 · 22 → 1 dolu → 2 · 8 → 1, 2 dolu → 3 · 29 → 1, 2, 3 dolu → 4 · 6 → 6
Tablo: [—, 15, 22, 8, 29, —, 6]
36 % 7 = 1 → kovalar 1, 2, 3, 4 doludur ve 36'dan farklıdır; kova 5 boş → 5 yoklama, bulunamadı. Tüm anahtarlar aynı kovaya düştüğü için aramalar küme boyunca doğrusal aramaya dönüştü.
Çıktı Sorusu · Hash ile Arama
Soru 17: Zincirleme
Ayrı zincirleme kullanan m = 10 kovalı tabloya (h(x) = x % 10, yeni öğe listenin sonuna) sırayla 21, 31, 4, 11, 14, 41 ekleniyor. 11 ve 51 aranırken kaç anahtar karşılaştırılır? Yük faktörü nedir?
Cevabı göster
- 11: kova 1 listesi 21, 31, 11 → 3 karşılaştırma, bulundu.
- 51: kova 1 listesi 21, 31, 11, 41 sonuna kadar → 4 karşılaştırma, bulunamadı.
α = n/m = 6/10 = 0,6. Ortalama beklenti başarısız aramada 1 + α'dır; ama anahtarların çoğu aynı kovaya düştüğü için (kötü dağılım) kova 1'de arama doğrusal olur. Zincirlemede tablo hiç “dolmaz”; liste uzar.
Çoktan Seçmeli · Hash ile Arama
Soru 18: Hash Arama: En İyi ve En Kötü
Zincirleme kullanan bir hash tablosunda arama için en iyi ve en kötü durum karmaşıklıkları nedir?
B: Çakışma yoksa anahtarın kovası tek adımda bulunur. Kötü bir hash fonksiyonu tüm anahtarları tek kovaya yollarsa arama bağlı listede doğrusal aramaya dönüşür. Ortalama O(1), yük faktörü sabit tutulduğunda geçerlidir.
Çoktan Seçmeli · Hash ile Arama
Soru 19: Dolu Tablo
Doğrusal yoklama kullanan hashArama metoduyla, tamamen dolu bir tabloda tabloda olmayan bir anahtar aranırsa ne olur?
B: Döngü yalnızca boş (null) kovada durur; % m ile sondan başa dönüldüğü için dizi dışına da çıkılmaz ve tablo sonsuza dek dolaşılır. Çözüm: yük faktörünü sınırlamak (ör. α ≤ 0,75'te tabloyu büyütmek) ya da m yoklamadan sonra durmak.
Çıktı Sorusu · Ara Değer Arama
Soru 20: Tahmin Edilen İndis
araDegerArama (a) 10, 20, …, 100 dizisinde 70'i ve (b) 1, 2, …, 9, 1000 dizisinde 9'u kaç yoklamada bulur?
int pay = (aranan - dizi[bas]) * (son - bas); int indis = bas + pay / (dizi[son] - dizi[bas]);
Cevabı göster
(a) indis = 0 + (70 − 10) · 9 / (100 − 10) = 540 / 90 = 6 → dizi[6] = 70: 1 yoklama.
(b) indis = 0 + (9 − 1) · 9 / 999 = 0 → 1 < 9 → bas = 1; sonra 1 + 7·8/998 = 1, … Uç değer 1000 tahmini hep sola çeker: indisler 0, 1, …, 8 → 9 yoklama. İkili arama aynı aramayı 3 yoklamada bitirir.
Düzgün dağılımda O(log log n), çarpık dağılımda en kötü O(n).
Adım Adım Çalıştırma · Ara Değer Arama
Soru 21: Çarpık Dağılımda Ara Değer
araDegerArama(dizi, 8, 32) [2, 4, 8, 16, 32, 64, 128, 256] dizisinde çalışıyor. Her turda hangi indis tahmin edilir, kaç yoklama yapılır?
Dizi sıralı ama üstel artıyor (2, 4, 8, …, 256): düzgün dağılım varsayımı bozuk. Aranan 32.
indis = 0 + 210 / 254 = 0 (aşağı yuvarlanır); dizi[0] = 2 < 32 → bas = 1. 256 tahmini sola çeker.
indis = 1 + 168 / 252 = 1 (aşağı yuvarlanır); dizi[1] = 4 < 32 → bas = 2.
indis = 2 + 120 / 248 = 2 (aşağı yuvarlanır); dizi[2] = 8 < 32 → bas = 3.
indis = 3 + 64 / 240 = 3 (aşağı yuvarlanır); dizi[3] = 16 < 32 → bas = 4.
indis = 4 + 0 / 224 = 4; dizi[4] = 32 → return 4. 5 yoklama: ikili arama 3 yoklamada (3, 5, 4) bulurdu.
int araDegerArama(int[] dizi, int n, int aranan) { int bas = 0, son = n - 1; while (bas <= son && aranan >= dizi[bas] && aranan <= dizi[son]) { if (dizi[son] == dizi[bas]) return bas; int pay = (aranan - dizi[bas]) * (son - bas); int indis = bas + pay / (dizi[son] - dizi[bas]); if (dizi[indis] == aranan) return indis; if (dizi[indis] < aranan) bas = indis + 1; else son = indis - 1; } return -1; }
Çoktan Seçmeli · Ara Değer Arama
Soru 22: Ara Çarpımda Taşma
Ara değer aramada (aranan - dizi[bas]) * (son - bas) çarpımı için hangisi doğrudur?
D: Örneğin değerler 10⁹ mertebesinde ve son − bas 10⁶ ise çarpım int sınırını (2³¹ − 1) çok aşar. long ile hesaplanmalıdır. Önce bölmek (C) tam sayı bölmesinde sonucu değiştirir: çoğu zaman 0 çıkar.
Adım Adım Çalıştırma · Atlayarak Arama
Soru 23: Atlayarak Arama: Başarısız
atlayarakAraBul(dizi, 30, 16), D = [3, 8, 15, 21, 27, 34, 40, 46, 52, 59, 65, 71, 78, 84, 90, 97] için çalışıyor. Hangi indisler yoklanır, ne döner?
n = 16 → blok = √16 = 4. Aranan 30; her bloğun son öğesine bakılacak.
dizi[min(4, 16) − 1] = dizi[3] = 21 < 30 → bloğu atla.
konum = 4, atlama = 8. dizi[7] = 46 ≥ 30 → atlama biter; aranan [4, 8) bloğunda olabilir.
Doğrusal tarama: dizi[4] = 27 < 30 → konum = 5.
konum = 5 ≠ min(8, 16); dizi[5] = 34 < 30 yanlış → döngüden çıkılır.
dizi[5] = 34 ≠ 30 → −1. Yoklanan indisler 3, 7, 4, 5: 30, 27 ile 34 arasında olurdu. En kötü durum ≈ n/m + m − 1 = 7 yoklama.
int atlayarakAraBul(int[] dizi, int eleman, int n) { int blok = (int) Math.sqrt(n); int atlama = blok, konum = 0; while (dizi[Math.min(atlama, n) - 1] < eleman) { konum = atlama; atlama += blok; if (konum >= n) return -1; } while (dizi[konum] < eleman) { konum++; if (konum == Math.min(atlama, n)) return -1; } if (dizi[konum] == eleman) return konum; return -1; }
Çoktan Seçmeli · Atlayarak Arama
Soru 24: En İyi Blok Boyu
Atlayarak aramada blok boyu m iken en kötü yoklama ≈ n/m + (m − 1)'dir. n = 10.000 için en iyi m ve en kötü yoklama sayısı nedir?
A: f(m) = n/m + m − 1, f′(m) = −n/m² + 1 = 0 ⇒ m = √n = 100; 10.000/100 + 99 = 199 → O(√n). m = 50 için 200 + 49 = 249 yoklama; 14, ikili aramanın yoklama sayısıdır (⌊log₂ 10.000⌋ + 1).
Çıktı Sorusu · Üstel Arama
Soru 25: Üstel Aramada Yoklamalar
ustelArama(D, 27, 16) çağrısında (D önceki sorudaki dizi) hangi indisler yoklanır ve ne döner? İkili arama hangi aralıkta yapılır?
int ustelArama(int[] dizi, int aranan, int n) { if (dizi[0] == aranan) return 0; int konum = 1; while (konum < n && dizi[konum] <= aranan) konum *= 2; int bas = konum / 2; int son = Math.min(konum, n - 1); while (bas <= son) { int orta = (bas + son) / 2; if (dizi[orta] == aranan) return orta; if (dizi[orta] < aranan) bas = orta + 1; else son = orta - 1; } return -1; }
Cevabı göster
- dizi[0] = 3 ≠ 27
- Katlama: dizi[1] = 8, dizi[2] = 15, dizi[4] = 27 ≤ 27 → konum 1 → 2 → 4 → 8; dizi[8] = 52 > 27 → durur.
- Aralık [8/2, min(8, 15)] = [4, 8]; ikili arama: orta 6 (40 > 27) → son = 5; orta 4 → 27 bulundu.
Yoklanan indisler: 0, 1, 2, 4, 8, 6, 4 (7 yoklama); dönüş 4. İndis 4 iki kez yoklanır: katlama aşamasında ≤ testi, ikili aramada eşitlik testi. Maliyet O(log i), i = 4.
Çoktan Seçmeli · Üstel Arama
Soru 26: Üstel Arama Ne Zaman?
Üstel arama hangi durumda ikili aramadan daha uygundur?
C: Maliyet n'ye değil aranan öğenin indisine (i) bağlıdır: O(log i). Boyu bilinmeyen (sınırsız) listelerde ikili arama için önce bir üst sınır bulmak gerekir; katlama bunu yapar. A doğrusal aramanın, B ara değer aramanın, D atlayarak aramanın uygun olduğu durumlardır.
Çoktan Seçmeli · Üstel Arama
Soru 27: Sınırı Kırpmak
ustelArama içinde son = Math.min(konum, n - 1) yerine son = konum yazılırsa ne olabilir?
A: ArrayIndexOutOfBoundsException fırlatılabilir. Katlama konum ≥ n olunca da durur (ör. n = 16 iken konum 16). Bu durumda ikili arama aralığının sonu dizi dışını gösterir; orta = son'a ulaşınca dizi[16] okunur. Math.min sınırı dizinin içinde tutar.
Çoktan Seçmeli · Karşılaştırma
Soru 28: Hangi Arama?
Sıralı kayıtlar bir manyetik bantta tutuluyor; ileri okumak ucuz, geri sarmak çok pahalı. Hangi arama yöntemi en uygundur?
C: Atlayarak arama √n'lik bloklar halinde hep ileri gider; yalnızca son bloğa bir kez geri döner ve onu sırayla okur: O(√n). İkili ve ara değer arama ileri-geri büyük sıçramalar yapar; hash tablosu ise kayıtların ayrıca bir tabloya yerleştirilmesini ister.
Klasik Soru · Karşılaştırma
Soru 29: Doğrusal mı, İkili mi?
Doğrusal ve ikili aramayı avantaj ve dezavantajlarıyla karşılaştırın. Sırasız n öğeli bir dizide k sorgu yapılacaksa hangisini, hangi koşulda seçersiniz?
Cevabı göster
- Doğrusal: önkoşul yok, basit, bağlı listede de çalışır; en kötü ve ortalama O(n).
- İkili: O(log n), büyük veride çok hızlı; ama sıralı dizi ve indisle O(1) erişim ister.
k sorgu: doğrusal toplam O(k · n); bir kez sırala + ikili O(n log n + k log n). k küçükse (ör. tek sorgu) doğrusal; k, log n mertebesini aşınca sıralamanın maliyeti kendini çıkarır. Örnek: n = 10⁶, k = 1000: doğrusal ≈ 10⁹, sırala + ikili ≈ 2 · 10⁷ + 2 · 10⁴ karşılaştırma.
Yalnızca tam eşleşme gerekiyorsa hash tablosu ortalama O(1) ile üçüncü seçenektir.