Bölüm 2: Sıralama Algoritmaları
Çoktan Seçmeli · Sıralama Ölçütleri
Soru 1: Kararsız Algoritma
Kayıtlar yalnızca sayıya göre sıralanıyor: (3, A), (1, B), (3, C). Aşağıdaki algoritmalardan hangisi (sunumdaki kodlarıyla) A ile C'nin göreli sırasını bozabilir?
C: Seçimli sıralama ilk turda en küçük (1, B)'yi baştaki (3, A) ile takas eder: (1, B), (3, C), (3, A). Uzun mesafeli takas eşit anahtarların sırasını bozar. Kabarcık (yalnızca > ise takas), eklemeli (yalnızca > olanı kaydırır) ve birleştirme (eşitlikte soldan alır) kararlıdır.
Adım Adım Çalıştırma · Kabarcık Sıralaması
Soru 2: Bayraklı Kabarcık: Turlar
Bayraklı kabarcık sıralaması [5, 2, 4, 6, 1, 3] dizisine uygulanıyor. Her tur sonunda dizi nedir, algoritma hangi turda durur?
n = 6. Her tur komşu çiftleri soldan sağa karşılaştırır; tur sonunda kalanların en büyüğü sona yerleşir.
Tur i = 0: 5 karşılaştırma, 4 takas. 6 son yerine (indis 5) oturdu; bayrak true.
Tur i = 1: 4 karşılaştırma, 2 takas. 5 son yerine (indis 4) oturdu; bayrak true.
Tur i = 2: 3 karşılaştırma, 2 takas. 4 son yerine (indis 3) oturdu; bayrak true.
Tur i = 3: 2 karşılaştırma, 1 takas. 3 son yerine (indis 2) oturdu; bayrak true.
Tur i = 4: 1 karşılaştırma, hiç takas yok → bayrak false → break. Toplam 5 + 4 + 3 + 2 + 1 = 15 karşılaştırma, 9 takas.
boolean yerDegistiMi; for(int i = 0; i < n - 1; i++) { yerDegistiMi = false; for(int j = 0; j < n - 1 - i; j++) { if(dizi[j] > dizi[j+1]) { int gecici = dizi[j]; dizi[j] = dizi[j+1]; dizi[j+1] = gecici; yerDegistiMi = true; } } if(yerDegistiMi == false) break; }
Çoktan Seçmeli · Kabarcık Sıralaması
Soru 3: Sıralı Girdide Bayrak
1000 öğeli, zaten artan sıralı bir diziye bayraklı kabarcık sıralaması uygulanırsa kaç karşılaştırma yapılır?
C: İlk turda 999 komşu çift karşılaştırılır, hiç takas olmaz; bayrak false kalır ve break ile çıkılır: n − 1 = 999 → Θ(n). Bayraksız sürüm 499.500 = n(n − 1)/2 karşılaştırma yapardı.
Çıktı Sorusu · Eklemeli Sıralama
Soru 4: Karşılaştırma ve Kaydırma Sayısı
Eklemeli sıralama [5, 2, 4, 6, 1, 3] dizisini sıralarken dizi[j] > gecici karşılaştırması kaç kez yapılır, kaç kaydırma yapılır?
for(int i = 1; i < n; i++) { int gecici = dizi[i]; int j = i - 1; while(j >= 0 && dizi[j] > gecici) { dizi[j+1] = dizi[j]; j = j - 1; } dizi[j+1] = gecici; }
Cevabı göster
| i | gecici | karş. | kaydırma | sonra |
|---|---|---|---|---|
| 1 | 2 | 1 | 1 | 2 5 4 6 1 3 |
| 2 | 4 | 2 | 1 | 2 4 5 6 1 3 |
| 3 | 6 | 1 | 0 | 2 4 5 6 1 3 |
| 4 | 1 | 4 | 4 | 1 2 4 5 6 3 |
| 5 | 3 | 4 | 3 | 1 2 3 4 5 6 |
Toplam 12 karşılaştırma, 9 kaydırma. Kaydırma = ters çift sayısı (9). i = 1 ve i = 4'te j = −1'e inilince j >= 0 yanlış olur, ek karşılaştırma yapılmaz.
Çoktan Seçmeli · Eklemeli Sıralama
Soru 5: İkili Arama ile Ekleme
Eklemeli sıralamada anahtarın yerleşeceği konum, sıralı kısımda ikili arama ile bulunursa en kötü durum zaman karmaşıklığı ne olur?
C: Karşılaştırmalar O(n log n)'e iner, ama anahtara yer açmak için ondan büyük öğelerin yine tek tek kaydırılması gerekir; ters sıralı girdide 1 + 2 + … + (n − 1) kaydırma → toplam Θ(n²).
Adım Adım Çalıştırma · Eklemeli Sıralama
Soru 6: Her Turdan Sonra Yazdırma
Her dış turdan sonra yazdıran eklemeli sıralama A = {5, 7, 3, 4, 2, 8} için ne yazdırır?
i = 1: anahtar = 7, A[0] = 5 ≤ 7 → while hiç dönmez; 7 yerinde kalır. Dizi değişmeden yazdırılır.
anahtar = 3. Kendinden büyük 2 öğe birer sağa kaydırıldı; j = -1 olunca koşul yanlış. Boşalan hücre j + 1 = 0.
A[0] = 3; A[0..2] sıralı. Satır yazdırılır.
anahtar = 4. Kendinden büyük 2 öğe birer sağa kaydırıldı; j = 0 olunca koşul yanlış. Boşalan hücre j + 1 = 1.
A[1] = 4; A[0..3] sıralı. Satır yazdırılır.
anahtar = 2. Kendinden büyük 4 öğe birer sağa kaydırıldı; j = -1 olunca koşul yanlış. Boşalan hücre j + 1 = 0.
A[0] = 2; A[0..4] sıralı. Satır yazdırılır.
i = 5: anahtar = 8, solundaki 7 ≤ 8 → kaydırma yok, 8 yerinde kalır. Dizi değişmeden yazdırılır. Döngü biter: 5 satır yazıldı, son satır sıralı dizidir.
for (int i = 1; i < A.length; ++i) { int anahtar = A[i]; int j = i - 1; while (j >= 0 && A[j] > anahtar) { A[j + 1] = A[j]; j = j - 1; } A[j + 1] = anahtar; System.out.println(Arrays.toString(A)); }
Çoktan Seçmeli · Eklemeli Sıralama
Soru 7: Durum ve Sınır
Eklemeli sıralamanın çalışma süresi için hangisi doğrudur?
D: Sıralı girdide her anahtar için tek karşılaştırma yapılır: n − 1 → Θ(n); ters sıralıda n(n − 1)/2 → Θ(n²). Alt ve üst sınır farklı fonksiyonlar olduğundan tüm girdiler için tek bir Θ yazılamaz; C'deki çıkarım yanlıştır. Kaydırma olmasa da n − 1 karşılaştırma yapıldığı için B yanlıştır.
Çıktı Sorusu · Seçimli Sıralama
Soru 8: Seçimli: Ekran Çıktısı
Dizi [7, 3, 9, 4, 2] iken aşağıdaki kod ne yazdırır? Kaç gerçek takas yapılır?
for (int i = 0; i < dizi.length - 1; i++) { int gecici = i; for (int j = i + 1; j < dizi.length; j++) { if (dizi[j] < dizi[gecici]) { gecici = j; } } if (gecici != i) { yerDegistir(dizi, i, gecici); } System.out.println(Arrays.toString(dizi)); }
Cevabı göster
[2, 3, 9, 4, 7] [2, 3, 9, 4, 7] [2, 3, 4, 9, 7] [2, 3, 4, 7, 9]
- i = 0: en küçük 2 (indis 4) ↔ 7.
- i = 1: en küçük zaten 3 →
gecici == i, takas yok; satır değişmeden yazılır. - i = 2: 4 ↔ 9. i = 3: 7 ↔ 9.
3 takas; karşılaştırma her durumda 4 + 3 + 2 + 1 = 10 → Θ(n²).
Adım Adım Çalıştırma · Shell Sıralaması
Soru 9: Shell Sıralaması İzleme
kabukSirala [9, 8, 3, 7, 5, 6, 4, 1] dizisine uygulanıyor. Her aralık değerinden sonra dizi nedir?
n = 8; aralık dizisi n/2 = 4, 2, 1. Aynı renkteki öğeler (aralarında aralik kadar indis olanlar) birlikte eklemeli sıralanır.
aralik = 4: gruplar [9, 5], [8, 6], [3, 4], [7, 1].
Her grup kendi içinde sıralandı (3 kaydırma) → [5, 6, 3, 1, 9, 8, 4, 7].
aralik = 2: gruplar [5, 3, 9, 4], [6, 1, 8, 7].
Her grup kendi içinde sıralandı (5 kaydırma) → [3, 1, 4, 6, 5, 7, 9, 8].
aralik = 1 sıradan eklemeli sıralamadır; dizi neredeyse sıralı olduğu için yalnızca 3 kaydırma gerekti. Sonuç [1, 3, 4, 5, 6, 7, 8, 9].
void kabukSirala(int[] dizi) { int n = dizi.length; for (int aralik = n / 2; aralik > 0; aralik /= 2) for (int i = aralik; i < n; i++) { int gecici = dizi[i], j = i; while (j >= aralik && dizi[j - aralik] > gecici) { dizi[j] = dizi[j - aralik]; j -= aralik; } dizi[j] = gecici; } }
Çoktan Seçmeli · Shell Sıralaması
Soru 10: Shell Sıralamasının Özellikleri
Shell sıralaması (n/2, n/4, …, 1 aralıklarıyla) için hangisi doğrudur?
D: Önceki turlar uzaktaki küçük öğeleri tek hamlede öne taşır; aralık = 1 turu bu yüzden az iş yapar. Shell sıralaması yerindedir (O(1) ek bellek) ve kararsızdır: farklı gruplardaki eşit öğeler birbirinin üzerinden atlayabilir.
Adım Adım Çalıştırma · Birleştirme Sıralaması
Soru 11: İki Sıralı Diziyi Birleştirme
Birleştirme adımı A = [4, 6, 15, 18] ve B = [2, 9, 10, 21] dizilerine uygulanıyor. C hangi sırayla dolar, kaç karşılaştırma yapılır?
İki sıralı dizi: A = [4, 6, 15, 18], B = [2, 9, 10, 21]. Yalnızca iki dizinin önündeki (sarı) öğeler karşılaştırılır; C boş.
A[0] = 4 > B[0] = 2 → C[0] = 2; j ve k ilerler.
A[0] = 4 ≤ B[1] = 9 → C[1] = 4; i ve k ilerler.
A[1] = 6 ≤ B[1] = 9 → C[2] = 6; i ve k ilerler.
A[2] = 15 > B[1] = 9 → C[3] = 9; j ve k ilerler.
A[2] = 15 > B[2] = 10 → C[4] = 10; j ve k ilerler.
A[2] = 15 ≤ B[3] = 21 → C[5] = 15; i ve k ilerler.
A[3] = 18 ≤ B[3] = 21 → C[6] = 18; i ve k ilerler. A bitti; ilk while sona erer.
B'de kalan 21 karşılaştırmasız kopyalanır. Sonuç [2, 4, 6, 9, 10, 15, 18, 21]: 8 yazma, 7 karşılaştırma → Θ(n).
int i = 0, j = 0, k = 0; while (i < A.length && j < B.length) { if (A[i] <= B[j]) C[k++] = A[i++]; else C[k++] = B[j++]; } while (i < A.length) C[k++] = A[i++]; while (j < B.length) C[k++] = B[j++];
Çıktı Sorusu · Birleştirme Sıralaması
Soru 12: birlestir Çağrıları
birlestirmeliSirala(dizi, 0, 6) çağrısı [38, 27, 43, 3, 9, 82, 10] dizisini sıralarken birlestir kaç kez çağrılır? İlk dört birleştirmenin sonucu (birleştirilen aralık) nedir?
void birlestirmeliSirala(int[] dizi, int sol, int sag) { if (sol < sag) { int orta = sol + (sag - sol) / 2; birlestirmeliSirala(dizi, sol, orta); birlestirmeliSirala(dizi, orta + 1, sag); birlestir(dizi, sol, orta, sag); } }
Cevabı göster
birlestir 6 kez (n − 1) çağrılır. Sırasıyla:
- [0..1] → [27, 38]
- [2..3] → [3, 43]
- [0..3] → [3, 27, 38, 43]
- [4..5] → [9, 82]
- [4..6] → [9, 10, 82]
- [0..6] → [3, 9, 10, 27, 38, 43, 82]
Sol yarı tamamen sıralanmadan sağ yarıya geçilmez (derinlik öncelikli). orta = sol + (sag − sol)/2 olduğu için sol yarı bir öğe fazla alır: [0..3] ve [4..6].
Çoktan Seçmeli · Birleştirme Sıralaması
Soru 13: 8 Öğede En Çok Karşılaştırma
Birleştirme sıralaması 8 öğeli bir diziyi en kötü durumda en fazla kaç öğe karşılaştırmasıyla sıralar?
B: m öğeli bir birleştirme en fazla m − 1 karşılaştırma ister. Düzeyler: 4 birleştirme × 1 + 2 × 3 + 1 × 7 = 17. 24 = n log₂ n üst tahminidir; 28 = n(n − 1)/2 basit algoritmaların sayısıdır; 7 yalnızca son birleştirmedir.
Çoktan Seçmeli · Birleştirme Sıralaması
Soru 14: Eşitlikte Hangisi?
birlestir metodunda L[i] <= R[j] koşulu L[i] < R[j] olarak değiştirilirse ne olur?
B: Eşitlikte artık sağ yarıdaki (R) öğe önce alınır; eşit anahtarlı iki kaydın göreli sırası bozulur. Sonuç yine sıralıdır ve karşılaştırma sayısı değişmez; yalnızca kararlılık (stable) kaybolur. Kayıtlar başka bir alana göre önceden sıralanmışsa bu fark önemlidir.
Klasik Soru · Birleştirme Sıralaması
Soru 15: Ters Çift Sayımı
Bir dizideki ters çift sayısını (i < j iken dizi[i] > dizi[j]) O(n log n) sürede bulan bir yöntem önerin. [3, 1, 2, 5, 4] için sonucu bulun.
Cevabı göster
Birleştirme sıralaması şöyle değiştirilir: birlestir içinde sağdan (R'den) bir öğe alındığında, L'de kalan tüm öğeler ondan büyüktür ve onunla ters çift oluşturur: sayaca L.length − i eklenir. Sol ve sağ yarının kendi ters çiftleri özyinelemeyle sayılır.
[3, 1, 2, 5, 4]: ters çiftler (3,1), (3,2), (5,4) → 3. Bu sayı eklemeli sıralamanın kaydırma, kabarcık sıralamasının takas sayısıdır.
Toplam iş birleştirme sıralamasıyla aynıdır: T(n) = 2T(n/2) + Θ(n) = Θ(n log n). Kaba kuvvet (tüm çiftler) Θ(n²) sürer.
Adım Adım Çalıştırma · Hızlı Sıralama
Soru 16: Lomuto Bölümleme
parcala(dizi, 0, 7) [7, 2, 1, 6, 8, 5, 3, 4] dizisi için çalışıyor. Her j'de i ve dizi nasıl değişir, metot ne döndürür?
pivot = dizi[7] = 4 (koyu); i = −1: ≤ pivot bölgesi (mavi) boş. Kırmızı: > pivot, beyaz: henüz bakılmadı.
j = 0: 7 > 4 → yalnızca j ilerler; kırmızı bölge büyür.
j = 1: 2 ≤ 4 → i = 0; takas(dizi, 0, 1) → [2, 7, 1, 6, 8, 5, 3, 4].
j = 2: 1 ≤ 4 → i = 1; takas(dizi, 1, 2) → [2, 1, 7, 6, 8, 5, 3, 4].
j = 3: 6 > 4 → yalnızca j ilerler; kırmızı bölge büyür.
j = 4: 8 > 4 → yalnızca j ilerler; kırmızı bölge büyür.
j = 5: 5 > 4 → yalnızca j ilerler; kırmızı bölge büyür.
j = 6: 3 ≤ 4 → i = 2; takas(dizi, 2, 6) → [2, 1, 3, 6, 8, 5, 7, 4].
Döngü bitti: takas(dizi, i + 1 = 3, 7) → [2, 1, 3, 4, 8, 5, 7, 6]. return 3: pivot kesin yerinde; solu ≤ 4, sağı > 4. 7 karşılaştırma → Θ(n).
int parcala(int[] dizi, int alt, int ust) { int pivot = dizi[ust]; int i = alt - 1; for (int j = alt; j < ust; j++) { if (dizi[j] <= pivot) { i++; takas(dizi, i, j); } } takas(dizi, i + 1, ust); return i + 1; }
Çoktan Seçmeli · Hızlı Sıralama
Soru 17: Sıralı Girdi ve Son Öğe Pivot
Son öğeyi pivot alan hızlı sıralama, 1000 öğeli zaten sıralı bir diziyle çağrılırsa kaç karşılaştırma yapar ve özyineleme derinliği ne olur?
B: Pivot her seferinde en büyük öğedir; bölümleme yalnızca pivotu ayırır: 999 + 998 + … + 1 = 499.500 karşılaştırma ve n düzeyli özyineleme (T(n) = T(n − 1) + Θ(n) → Θ(n²)). Rastgele pivot ya da üçün ortancası bu durumu önler. 9.966 ≈ n log₂ n dengeli bölmenin sayısıdır.
Adım Adım Çalıştırma · Heap Sort
Soru 18: Max-Heap Kurma
yiginSirala metodunun ilk aşaması (heap kurma) [2, 7, 4, 1, 8, 6, 5] dizisine uygulanıyor. Hangi takaslar yapılır ve oluşan max-heap nedir?
Dizi tam ikili ağaç olarak düşünülür: dizi[i]'nin çocukları 2i + 1 ve 2i + 2. Yapraklar (i ≥ 3) zaten tek öğeli heap'tir; i = n/2 − 1 = 2'den köke doğru süzülür.
yiginlastir(i = 2): 4 en büyük çocuğundan küçük → 4 ↔ 6 (indis 2 ↔ 5). Dizi [2, 7, 6, 1, 8, 4, 5].
yiginlastir(i = 1): 7 en büyük çocuğundan küçük → 7 ↔ 8 (indis 1 ↔ 4). Dizi [2, 8, 6, 1, 7, 4, 5].
yiginlastir(i = 0): 2 en büyük çocuğundan küçük → 2 ↔ 8 (indis 0 ↔ 1). Dizi [8, 2, 6, 1, 7, 4, 5].
Süzme sürer: 2 en büyük çocuğundan küçük → 2 ↔ 7 (indis 1 ↔ 4). Dizi [8, 7, 6, 1, 2, 4, 5]. Max-heap hazır: kök 8 en büyük öğe.
2. aşamanın ilk turu: kök 8 ↔ dizi[6] = 5 → 8 sıralı bölgeye geçer (kesikli); heap boyutu 6. yiginlastir(0): 5 ↔ 7 → [7, 5, 6, 1, 2, 4, 8].
void yiginSirala(int[] dizi) { int n = dizi.length; for (int i = n / 2 - 1; i >= 0; i--) yiginlastir(dizi, n, i); // 2. aşama: kökü sona al, süz ... }
Çoktan Seçmeli · Heap Sort
Soru 19: Heap Sort Özellikleri
Heap sort için aşağıdakilerden hangisi doğrudur?
D: n − 1 kez kök sona alınır ve O(log n)'de süzülür; ek dizi gerekmez. Aşağıdan yukarı kurma O(n)'dir (A ters), kök–son takası kararlılığı bozar (B yanlış) ve heap sort uyarlanabilir değildir: sıralı girdide de Θ(n log n) sürer.
Çoktan Seçmeli · Doğrusal Zamanlı Sıralama
Soru 20: Karar Ağacı Sınırı
3 farklı öğeyi yalnızca karşılaştırmayla sıralayan her algoritma en kötü durumda en az kaç karşılaştırma yapmak zorundadır?
B: Karar ağacının 3! = 6 yaprağı olmalıdır; yüksekliği h olan ikili ağacın en fazla 2ʰ yaprağı vardır: 2ʰ ≥ 6 ⇒ h ≥ ⌈log₂ 6⌉ = 3. İki karşılaştırma yalnızca 4 sonucu ayırt edebilir. Genel olarak log₂(n!) = Ω(n log n).
Adım Adım Çalıştırma · Doğrusal Zamanlı Sıralama
Soru 21: Saymalı Sıralama İzleme
saymaliSirala [3, 1, 4, 1, 3, 0] dizisi için çalışıyor. Sayaç dizisi ve çıktı dizisi nasıl dolar?
Sayma döngüsü bitti: sayac[x] = x anahtarının adedi → [1, 2, 0, 2, 1]. maks = 4 olduğu için sayaç 5 hücrelidir.
Önek toplamı: sayac[x] = anahtarı ≤ x olan öğe sayısı → [1, 3, 3, 5, 6]. sayac[x] − 1, x'in çıktıdaki son konumudur.
i = 5: dizi[5] = 0 → cikti[sayac[0] − 1] = cikti[0] = 0; sayac[0] = 0.
i = 4: dizi[4] = 3 → cikti[sayac[3] − 1] = cikti[4] = 3; sayac[3] = 4.
i = 3: dizi[3] = 1 → cikti[sayac[1] − 1] = cikti[2] = 1; sayac[1] = 2.
i = 2: dizi[2] = 4 → cikti[sayac[4] − 1] = cikti[5] = 4; sayac[4] = 5.
i = 1: dizi[1] = 1 → cikti[sayac[1] − 1] = cikti[1] = 1; sayac[1] = 1.
i = 0: dizi[0] = 3 → cikti[sayac[3] − 1] = cikti[3] = 3; sayac[3] = 3. Çıktı: [0, 1, 1, 3, 3, 4]. Karşılaştırma yok: Θ(n + k).
int[] saymaliSirala(int[] dizi) { int maks = enBuyuk(dizi); int[] sayac = new int[maks + 1]; for (int x : dizi) sayac[x]++; for (int i = 1; i <= maks; i++) sayac[i] += sayac[i - 1]; int[] cikti = new int[dizi.length]; for (int i = dizi.length - 1; i >= 0; i--) { cikti[sayac[dizi[i]] - 1] = dizi[i]; sayac[dizi[i]]--; } return cikti; }
Çıktı Sorusu · Doğrusal Zamanlı Sıralama
Soru 22: Basamak Sıralaması Geçişleri
[329, 457, 657, 839, 436, 720, 355] dizisi LSD basamak sıralamasıyla (her geçişte kararlı saymalı sıralama) sıralanıyor. Her geçişten sonraki dizi nedir?
Cevabı göster
| Geçiş | Anahtar | Dizi |
|---|---|---|
| 1 | birler | [720, 355, 436, 457, 657, 329, 839] |
| 2 | onlar | [720, 329, 436, 839, 355, 457, 657] |
| 3 | yüzler | [329, 355, 436, 457, 657, 720, 839] |
2. geçişte onlar basamağı 2 olan 720 ile 329, 1. geçişteki sıralarını korur (kararlılık). Kararsız bir ara sıralama, önceki basamakların sırasını bozardı. d = 3, b = 10: Θ(d(n + b)).
Çoktan Seçmeli · Karşılaştırma
Soru 23: Hangi Algoritma?
Disk üzerinde, belleğe sığmayan büyük bir dosyayı sıralamak ya da bir bağlı listeyi sıralamak için en uygun algoritma hangisidir?
A: Birleştirme sıralaması rastgele erişim gerektirmez; öğeleri sırayla okuyup yazar. Dosya parça parça sıralanıp birleştirilir, bağlı liste de ek dizi olmadan birleştirilebilir. Heap sort ve hızlı sıralama indisle rastgele erişime dayanır.