Bölüm 19: Temel Sıralama Algoritmaları

C ile Veri Yapıları ve Algoritmalar · Çalışma Soruları
KavramlarSeçimliEklemeliKabarcıkSayarakShell ve kovaAlt sınırÖzet
Sercan KÜLCÜ

Çoktan Seçmeli · Sıralama Kavramları

Soru 1: Süslü Parantezli SWAP

SWAP makrosu do { … } while (0) yerine yalnız süslü parantezle tanımlanmıştır. Program derlenip çalıştırılırsa ne olur?

#define SWAP(A, B) { int t = A; A = B; B = t; }
int main(void) {
    int a = 2, b = 1;
    if (a > b)
        SWAP(a, b);
    else
        printf("sirali\n");
    printf("%d %d\n", a, b);
    return 0;
}

B: SWAP(a, b); açılınca { … }; olur. Bloktan sonraki noktalı virgül boş bir deyimdir; if bu blokla biter ve else yetim kalır (zig cc: "expected expression"). do { … } while (0) tek bir deyim gibi davranır ve noktalı virgülü yutar.

Çoktan Seçmeli · Sıralama Kavramları

Soru 2: Kararlı Sıralama

Tutanaklar (Ali, 70), (Can, 85), (Ece, 70), (Banu, 85), (Deniz, 60) sırasıyla geliyor. Nota göre artan sırada kararlı bir sıralamanın çıktısı hangisidir?

C: Kararlı sıralamada eşit anahtarlı tutanaklar girdideki göreli sıralarını korur: Ali Ece'den, Can Banu'dan önce gelir. A ve D 70'leri, B ve D 85'leri ters çevirir. Eklemeli sıralamayla (a[j] > v) denenen program da C'yi verdi.

Adım Adım Çalıştırma · Seçimli Sıralama

Soru 3: Seçimli Sıralama Kararlı mı?

selection(a, 0, 4) çağrılıyor; a = [3a, 5, 3b, 1, 2] (3a ve 3b aynı değer, etiketler yalnız sırayı izlemek için). Eşit öğelerin sırası korunur mu?

3a0513b21324

İki 3 değeri etiketlendi: 3a önde, 3b arkada. Kararlı bir sıralama bu sırayı korumalıdır.

3a0513b21324imin

Tur i = 0: a[0..4] taranır, en küçük a[3] = 1.

10513b23a324

SWAP(a[0], a[3]): 1 öne geldi; 3a uzaktaki 3. konuma atlayarak 3b'nin arkasına geçti.

10513b23a324imin

Tur i = 1: a[1..4] taranır, en küçük a[4] = 2.

10213b23a354

SWAP(a[1], a[4]): 2 öne geldi, 5 4. konuma atladı.

10213b23a354min

Tur i = 2: a[2..4] taranır, en küçük a[2] = 3b.

10213b23a354

min = i: takas kendisiyle yapılır, dizi değişmez.

10213b23a354min

Tur i = 3: a[3..4] taranır, en küçük a[3] = 3a.

10213b23a354

min = i: takas kendisiyle yapılır, dizi değişmez.

10213b23a354

Sonuç sıralı ama 3b, 3a'nın önünde: uzak takas yüzünden seçimli sıralama kararlı değildir.

void selection(int a[], int L, int R) {
    for (int i = L; i < R; i++) {
        int min = i;
        for (int j = i + 1; j <= R; j++)
            if (kucuk(a[j], a[min]))
                min = j;
        SWAP(a[i], a[min]);
    }
}

Çoktan Seçmeli · Seçimli Sıralama

Soru 4: Seçimlide Sayım

n = 8 öğeli, zaten sıralı bir dizide selection kaç karşılaştırma ve kaç SWAP çağrısı yapar?

A: İç döngü dizinin sıralı olduğunu bilmez: 7 + 6 + … + 1 = 28 karşılaştırma. Her dış turun sonunda SWAP çağrılır; min = i olduğu için öğe kendisiyle takaslanır: 7 çağrı, gerçek yer değişikliği 0. Karşılaştırma sayısı girdiden bağımsızdır.

Hata Bulma · Seçimli Sıralama

Soru 5: En Küçük Değeri Tutmak

Bu seçimli sıralamada min indis yerine değeri tutuyor. a = [4, 2, 5, 1] için selection(a, 0, 3) sonrası dizi nedir? Hatayı düzeltin.

void selection(int a[], int L, int R) {
    for (int i = L; i < R; i++) {
        int min = a[i];
        for (int j = i + 1; j <= R; j++)
            if (a[j] < min)
                min = a[j];
        SWAP(a[i], min);
    }
}
Cevabı göster

Sonuç [1, 1, 1, 1]:

  • i = 0: min = 1. SWAP(a[0], min) a[0]'a 1 yazar, 4 ise yerel min'e gider ve kaybolur: [1, 2, 5, 1].
  • i = 1: en küçük yine 1 (a[3]) → [1, 1, 5, 1]. i = 2: → [1, 1, 1, 1].

En küçük öğe a[i]'ye kopyalanır ama bulunduğu hücreye a[i]'nin eski değeri yazılmaz; değerler çoğalır, 4, 2 ve 5 silinir. Takas için indis gerekir: int min = i;, if (a[j] < a[min]) min = j;, SWAP(a[i], a[min]);

Çıktı Sorusu · Eklemeli Sıralama

Soru 6: Karşılaştırma ve Kaydırma

Eklemeli sıralamaya sayaçlar eklenmiştir (virgül işleci önce sayacı artırır, sonra karşılaştırır). Program ne yazdırır?

long karsil = 0, kaydir = 0;
void insertion_say(int a[], int L, int R) {
    for (int i = L + 1; i <= R; i++) {
        int v = a[i], j = i - 1;
        while (j >= L && (karsil++, a[j] > v)) {
            a[j + 1] = a[j];  j--;  kaydir++;
        }
        a[j + 1] = v;
    }
}
/* main: int a[] = {3, 7, 4, 1, 5};
   insertion_say(a, 0, 4);
   printf("%ld %ld", karsil, kaydir); */
Cevabı göster

Çıktı: 8 5

  • i = 1 (7): 3 > 7 yanlış → 1 karşılaştırma.
  • i = 2 (4): 7 kaydı, 3 durdurdu → 2 karşılaştırma, 1 kaydırma.
  • i = 3 (1): 7, 4, 3 kaydı; j = −1 olunca j >= L yanlış, a[j] hiç sınanmaz → 3 karşılaştırma, 3 kaydırma.
  • i = 4 (5): 7 kaydı, 4 durdurdu → 2 karşılaştırma, 1 kaydırma.

Kaydırma sayısı evrik sayısına eşittir: (3,1), (7,4), (7,1), (7,5), (4,1) = 5.

Çoktan Seçmeli · Eklemeli Sıralama

Soru 7: j >= 0 Sınırı

İç döngü koşulu j >= L yerine j >= 0 yazılmıştır. a = [9, 8, 5, 3, 4] için insertion(a, 2, 4) sonrası dizi nedir?

while (j >= 0 && a[j] > v) {
    a[j + 1] = a[j];
    j--;
}
a[j + 1] = v;

D: Yalnız a[2..4] sıralanmalıdır. 3 yerleştirilirken 5, 8 ve 9 sağa kaydırılır: [3, 9, 8, 5, 4]. 4 ise 9, 8, 5'i kaydırıp 3'ün arkasında durur: [3, 4, 9, 8, 5]. Alt dizinin dışı bozuldu, alt dizi de sıralanmadı. Doğru sınırla sonuç A olur.

Çoktan Seçmeli · Kabarcık Sıralaması

Soru 8: Kabarcıkta Takas

bubble yordamı [3, 5, 1, 4, 2] dizisini sıralarken kaç takas yapar?

B: Komşu takası tam bir evriği giderir; takas sayısı evrik sayısına eşittir: (3,1), (3,2), (5,1), (5,4), (5,2), (4,2) = 6. Karşılaştırma ise erken durma olmadan her girdide n(n − 1)/2 = 10'dur (C ile sayıldı).

Adım Adım Çalıştırma · Sayarak Sıralama

Soru 9: Sayarak Sıralamada Kararlılık

counting_sort a = [2, 0, 2, 1, 0, 2], r = 5, k = 2 ile çağrılıyor (etiketler eşitleri izlemek için). c ve b dizileri nasıl dolar?

a2a00a12b2130b42c5c201132b_0_1_2_3_4_5

L1–L2: c[x] = x değerinin kaç kez geçtiği: iki 0, bir 1, üç 2.

a2a00a12b2130b42c5c203162b_0_1_2_3_4_5

L3 birikimli toplam: c[x] = x'ten küçük ya da eşit öğe sayısı. 2'ler b[3..5]'e gidecek.

a2a00a12b2130b42c5c203152b_0_1_2_3_42c5

L4 sağdan başlar: a[5] = 2c → b[5] (2'lerin en sağı); c[2] = 5.

a2a00a12b2130b42c5c103152b_00b1_2_3_42c5

L4: a[4] = 0b → b[1]; c[0] = 1 olur.

a2a00a12b2130b42c5c102152b_00b112_3_42c5

L4: a[3] = 1 → b[2]; c[1] = 2 olur.

a2a00a12b2130b42c5c102142b_00b112_32b42c5

L4: a[2] = 2b → b[4]; c[2] = 4 olur.

a2a00a12b2130b42c5c002142b0a00b112_32b42c5

L4: a[1] = 0a → b[0]; c[0] = 0 olur.

a2a00a12b2130b42c5c002132b0a00b1122a32b42c5

L4: a[0] = 2a → b[3]; c[2] = 3 olur.

a2a00a12b2130b42c5c002132b0a00b1122a32b42c5

Sonuç [0a, 0b, 1, 2a, 2b, 2c]: eşitlerin sırası korundu. Sağdan gezildiği için her değerin son kopyası en sağdaki boş yere yazılır.

/* L1 */
for (int i = 0; i <= k; i++) c[i] = 0;
/* L2 */
for (int j = 0; j <= r; j++) c[a[j]]++;
/* L3 */
for (int i = 1; i <= k; i++)
    c[i] += c[i - 1];
/* L4 */
for (int j = r; j >= 0; j--) {
    b[c[a[j]] - 1] = a[j];
    c[a[j]]--;
}

Çoktan Seçmeli · Sayarak Sıralama

Soru 10: L4 Soldan Sağa

counting_sort'ta L4 döngüsü for (int j = 0; j <= r; j++) olarak yazılırsa ne olur?

A: c[x] hâlâ x'lerin bloğunun son konumunu gösterir. Soldan gezilince x'in ilk kopyası bloğun en sağına, sonuncusu en soluna yazılır: değerler doğru, eşitler ters. Sayılar için fark görünmez, ama basamağa göre sıralamada kararlılık gerekir ve sonuç bozulur.

Kod Yazma · Sayarak Sıralama

Soru 11: Negatif Değerlerle Sayarak

Değerleri [lo, hi] aralığında (negatif olabilir) n tamsayıyı kararlı biçimde sıralayan int sayarak_aralik(const int a[], int b[], int n, int lo, int hi) yordamını yazın. Sayaç dizisi heap'te ayrılsın; hata durumunda −1 dönsün.

Cevabı göster
int sayarak_aralik(const int a[], int b[], int n,
                   int lo, int hi) {
  if (hi < lo) return -1;
  int k = hi - lo + 1;
  int *c = calloc(k, sizeof *c);       /* sıfırlı */
  if (c == NULL) return -1;
  for (int j = 0; j < n; j++) c[a[j] - lo]++;
  for (int i = 1; i < k; i++) c[i] += c[i - 1];
  for (int j = n - 1; j >= 0; j--)     /* kararlı */
    b[--c[a[j] - lo]] = a[j];
  free(c);
  return 0;
}

Değer x, c[x − lo] hücresinde sayılır; böylece −2 indis 0'a düşer. a = [3, −2, 0, 3, −1, −2], lo = −2, hi = 3 için b = [−2, −2, −1, 0, 3, 3]. Zaman ve bellek O(n + k).

Adım Adım Çalıştırma · Shell ve Kova Sıralama

Soru 12: Shell ile Daha Az Kaydırma

shell_sort [5, 1, 6, 2, 4, 3] ile çağrılıyor (h = 3, 1). Hangi adımlarda kaydırma olur? Toplam kaydırma, düz eklemeli sıralamanınkiyle karşılaştırıldığında nasıldır?

501162234435

Evrik sayısı 8: düz eklemeli sıralama 8 kaydırma yapardı.

501162234435

Aralık h = 3: (a[0], a[3]), (a[1], a[4]), (a[2], a[5]) çiftleri ayrı ayrı eklemeli sıralanır.

201162534435

i = 3: v = 2, 1 kez 3 geri kaydırıldı → a[0] = 2. Toplam kaydırma 1.

201132534465

i = 5: v = 3, 1 kez 3 geri kaydırıldı → a[2] = 3. Toplam kaydırma 2.

201132534465

Son tur h = 1: sıradan eklemeli sıralama, ama dizi artık neredeyse sıralı.

102132534465

i = 1: v = 1, 1 kez 1 geri kaydırıldı → a[0] = 1. Toplam kaydırma 3.

102132435465

i = 4: v = 4, 1 kez 1 geri kaydırıldı → a[3] = 4. Toplam kaydırma 4.

102132435465

h = 0: bitti. Toplam 4 kaydırma; h = 3 turundaki iki uzak kaydırma 8 evrikten 6'sını birden giderdi.

void shell_sort(int a[], int n) {
    for (int h = n / 2; h > 0; h /= 2)
        for (int i = h; i < n; i++) {
            int v = a[i], j = i;
            while (j >= h && a[j - h] > v) {
                a[j] = a[j - h];
                j -= h;
            }
            a[j] = v;
        }
}

Klasik Soru · Shell ve Kova Sıralama

Soru 13: Kovalar

bucket_sort n = 5 ve a = [0,42, 0,32, 0,23, 0,52, 0,25] ile çağrılıyor. Her sayı hangi kovaya düşer? Dağıtım bittiğinde kovaların listeleri nedir? Bu girdi kova sıralaması için iyi midir?

Cevabı göster

Kova numarası ⌊5x⌋: 0,42 → 2, 0,32 → 1, 0,23 → 1, 0,52 → 2, 0,25 → 1.

kova01234
liste—0,23 → 0,25 → 0,320,42 → 0,52——

Her sayı kendi listesine sıralı eklenir (0,23, 0,32'nin önüne; 0,25 ikisinin arasına). Kovalar sırayla toplanınca [0,23, 0,25, 0,32, 0,42, 0,52].

Sayılar [0,2; 0,6) aralığında toplandığı için beş kovanın üçü boş, biri üç öğeli kaldı. Düzgün dağılım varsayımı zayıfladıkça kova içi eklemeli sıralamanın payı büyür; en kötü durumda O(n²).

Çoktan Seçmeli · Optimal Sıralama Zamanı

Soru 14: Altı Öğede Alt Sınır

6 farklı öğeyi sıralayan karşılaştırmalı bir algoritma en kötü durumda en az kaç karşılaştırma yapmak zorundadır?

C: Karar ağacının en az 6! = 720 yaprağı vardır. 2⁹ = 512 < 720 ≤ 1024 = 2¹⁰ olduğundan yükseklik en az ⌈lg 720⌉ = 10. Seçimli sıralama her girdide 15 karşılaştırma yapar; alt sınırın 5 fazlası.

Kod Yazma · Özet

Soru 15: Tutanakları Kararlı Sıralamak

typedef struct { char ad[12]; int not_; } ogrenci; tutanaklarını nota göre artan sırada, kararlı ve yerinde sıralayan void ogr_sirala(ogrenci a[], int n) yordamını eklemeli sıralamayla yazın.

Cevabı göster
void ogr_sirala(ogrenci a[], int n) {
  for (int i = 1; i < n; i++) {
    ogrenci v = a[i];            /* tutanak kopyası */
    int j = i - 1;
    while (j >= 0 && a[j].not_ > v.not_) {
      a[j + 1] = a[j];           /* struct ataması */
      j--;
    }
    a[j + 1] = v;
  }
}

Kararlılığı katı > sağlar: eşit notta kaydırma durur, öğe eşitinin arkasında kalır. >= yazılsaydı eşitler yer değiştirirdi. Struct ataması bütün alanları kopyalar; büyük tutanaklarda indis ya da işaretçi dizisi sıralamak daha ucuzdur. (Ali, 70), (Can, 85), (Ece, 70), (Banu, 85), (Deniz, 60) girdisi Deniz, Ali, Ece, Can, Banu verir.

Çoktan Seçmeli · Özet

Soru 16: Hangi Algoritma?

100 000 tutanaklı, neredeyse sıralı (yalnız birkaç tutanak yerinde değil) bir dizi kararlı biçimde sıralanacak; ek bellek kullanılmayacak. Hangisi en uygundur?

D: Eklemeli sıralama kararlı ve yerindedir; neredeyse sıralı veride kaydırma sayısı evrik sayısı kadar, yani çok azdır. Seçimli girdiye kördür (≈ n²/2 karşılaştırma) ve kararsızdır; Shell kararsızdır; sayarak sıralama ek bellek ister ve yalnız küçük tamsayı aralığında anlamlıdır.

Son

Bölüm 19: Temel Sıralama Algoritmaları — Çalışma Soruları
Konu anlatımı: Temel sıralama algoritmaları sunumu · Ders notu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.