YZ Destekli Kodlama Notları

Veri Yapıları · Ünite 4

Sıralama Algoritmaları (C#)

10 soruluk deneme testine geç ↓

1. Sıralama algoritması nedir?

Sıralama, çok sayıda ögeyi küçükten büyüğe, büyükten küçüğe, kısadan uzuna gibi bir ölçüte göre düzenleme işlemidir. Telefon rehberi alfabetik, kargo dağıtımı adrese göre, alışveriş sitesi fiyata ya da tarihe göre sıralar. Bilgisayarda en çok yapılan iki iş sıralama ve aramadır; bu yüzden en çok araştırılan konular arasındadır.

Sıralama algoritması, sırasız bir listeyi girdi olarak alıp üzerinde işlemler yapan ve sıralı bir dizi çıktı veren algoritmadır. Hepsi görünüşte aynı işi yapar; onları ayıran şey performans, yani çalışırken harcadıkları kaynak ve süredir.

Sıralı veri başka algoritmaları da hızlandırır: arama ve birleştirme algoritmaları sıralı listeyle çok daha verimli çalışır. Sıralama ayrıca veriyi standart hâle getirir ve insanın okuyabileceği çıktılar üretir; veritabanlarında ve böl-yönet yöntemlerinde doğrudan kullanılır.

Test için bir dizi sınıfı

Algoritmaları denemek için önce küçük bir dizi sınıfı yazılır: eleman ekleyen, yazdıran ve diziyi sıfırlayan üç metot. Sıralama metotları da bu sınıfın içine eklenir.

class Dizi
{
    private int[] arr;
    private int sonIndis;      // boyut - 1
    private int adet = 0;      // eklenen eleman sayısı

    public Dizi(int boyut) { arr = new int[boyut]; sonIndis = boyut - 1; }

    public void Ekle(int x) { arr[adet] = x; adet++; }

    public void Yazdir()
    {
        for (int i = 0; i <= sonIndis; i++) Console.Write(arr[i] + " ");
    }

    public void Temizle()
    {
        for (int i = 0; i <= sonIndis; i++) arr[i] = 0;
        adet = 0;
    }
}

Algoritmayı sıralı veriyle denemek anlamsızdır; işini görmek için dizi rastgele, sırasız sayılarla doldurulur. C#'ın Random sınıfı bunu yapar: NextDouble() 0 ile 1 arasında bir sayı verir, 100 ile çarpıp int'e çevirince 0–99 arası bir tam sayı elde edilir.

Dizi d = new Dizi(10);
Random rnd = new Random(100);
for (int i = 0; i < 10; i++)
    d.Ekle((int)(rnd.NextDouble() * 100));
d.Yazdir();   // ör. 96 15 66 90 35 94 71 61 34 14

2. Baloncuk sıralama (bubble sort)

Baloncuk sıralama, listedeki elemanları yan yana ikişer ikişer karşılaştırıp yanlış sıradaysa yerlerini değiştiren algoritmadır. Büyük eleman her turda bir baloncuk gibi listenin sonuna doğru kayar; adını buradan alır.

Bir tur: her komşu çift karşılaştırılır, en büyük sayı sona yerleşir.
Tur8 3 6 1 5 dizisi (artan)Ne oldu?
13 6 1 5 88 bütün komşularını geçip sona çıktı
23 1 5 6 86 yerine oturdu
31 3 5 6 83 ile 1 yer değiştirdi
41 3 5 6 8Değişiklik yok, sıralama bitti
public void BaloncukSirala()
{
    for (int dis = sonIndis; dis >= 1; dis--)          // her turda sınır bir azalır
        for (int ic = 0; ic <= dis - 1; ic++)
            if (arr[ic] > arr[ic + 1])                   // komşular yanlış sıradaysa
            {
                int temp = arr[ic];                      // yer değiştir (swap)
                arr[ic] = arr[ic + 1];
                arr[ic + 1] = temp;
            }
}

3. Seçerek sıralama (selection sort)

Seçerek sıralama, dizinin sıralanmamış kısmındaki en küçük elemanı seçip o kısmın başına koyan algoritmadır. 1. adımda tüm dizideki en küçük eleman bulunur ve 0. indisle yer değiştirir; 2. adımda 1. indisten sona kadar bakılır ve en küçük 1. indise gelir; böyle devam eder.

Adım8 3 6 1 5 dizisiNe oldu?
11 3 6 8 5En küçük 1 seçildi, baştaki 8 ile yer değiştirdi
21 3 6 8 5Kalanda en küçük 3, zaten yerinde: değişiklik yok
31 3 5 8 65 seçildi, 6 ile yer değiştirdi
41 3 5 6 86 seçildi, 8 ile yer değiştirdi
public void SecerekSirala()
{
    for (int dis = 0; dis <= sonIndis; dis++)
    {
        int min = dis;                                   // en küçüğün indisi
        for (int ic = dis + 1; ic <= sonIndis; ic++)
            if (arr[ic] < arr[min]) min = ic;
        int temp = arr[dis];                             // en küçüğü başa al
        arr[dis] = arr[min];
        arr[min] = temp;
    }
}

4. Ekleme sıralama (insertion sort)

Ekleme sıralama, sıradaki elemanı alıp önceden sıralanmış elemanlar arasındaki doğru yerine ekleyen algoritmadır. Kitaplığa kitap dizmek gibi: soldan başlarsın, her yeni kitabı önceki kitapların arasında olması gereken yere koyarsın.

Adım8 3 6 1 5 dizisiNe oldu?
Başlangıç8 | 3 6 1 5İlk eleman tek başına sıralı sayılır
13 8 | 6 1 53, 8'in önüne eklendi
23 6 8 | 1 56, 3 ile 8'in arasına eklendi
31 3 6 8 | 51 en başa eklendi
41 3 5 6 85, 3 ile 6'nın arasına eklendi
public void EklemeSirala()
{
    for (int dis = 1; dis <= sonIndis; dis++)
    {
        int temp = arr[dis];                             // yerleştirilecek eleman
        int ic = dis;
        while (ic > 0 && arr[ic - 1] >= temp)            // büyükleri bir sağa kaydır
        {
            arr[ic] = arr[ic - 1];
            ic--;
        }
        arr[ic] = temp;                                  // boşalan yere koy
    }
}

Fark: baloncuk ve seçerek sıralama elemanları yer değiştirerek çalışır; ekleme sıralama ise büyük elemanları sağa kaydırıp yeni geleni araya ekler. Dış döngü elemanları tek tek gezer, içteki while döngüsü sıradaki elemanı sıralı kısımda yerine yerleştirir.

5. Hızlı sıralama (quick sort)

Hızlı sıralama, diziden bir pivot eleman seçip diğer elemanları pivottan küçükler ve büyükler diye iki gruba ayıran, sonra her grubu aynı yöntemle özyinelemeli (recursive) olarak sıralayan algoritmadır. Dört algoritmanın en performanslısıdır, ama dikkatli yazılmazsa işlem yükü artar.

Pivot (en sağdaki 5) ayırma işleminden sonra kesin yerine oturur; iki grup ayrı ayrı sıralanır.
public void HizliSirala() { HizliSirala(0, arr.Length - 1); }

void HizliSirala(int sol, int sag)
{
    if (sol < sag)                                       // en az 2 eleman varsa
    {
        int p = Parcala(sol, sag);                       // pivot yerine oturdu
        HizliSirala(sol, p - 1);                         // küçükler grubu
        HizliSirala(p + 1, sag);                         // büyükler grubu
    }
}

int Parcala(int sol, int sag)
{
    int pivot = arr[sag];                                // en sağdaki eleman
    int i = sol;                                         // küçüklerin yazılacağı yer
    for (int j = sol; j < sag; j++)
        if (arr[j] < pivot)
        {
            (arr[i], arr[j]) = (arr[j], arr[i]);         // küçüğü sola al
            i++;
        }
    (arr[i], arr[sag]) = (arr[sag], arr[i]);             // pivotu araya koy
    return i;
}

8 3 6 1 5 dizisinde pivot 5'tir. Parcala küçükleri (3, 1) sola toplar ve pivotu araya koyar: 3 1 5 8 6. Sonra sol grup (3 1) ve sağ grup (8 6) ayrı ayrı sıralanır ve sonuç 1 3 5 6 8 olur.

6. Hangisi ne kadar hızlı?

Dört algoritma aynı rastgele dizilerle çalıştırılıp süreleri Stopwatch ile ölçülür: StartNew() saati başlatır, Stop() durdurur, ElapsedMilliseconds geçen süreyi verir, Restart() sıfırlayıp yeniden başlatır. Her algoritmadan önce dizi Temizle() ile sıfırlanıp yeniden rastgele doldurulur.

Algoritma1.000 eleman10.000 elemanArtış
Baloncuk6 ms614 ms≈ 100 kat
Seçerek3 ms299 ms≈ 100 kat
Ekleme2 ms207 ms≈ 100 kat
Hızlı0,8 ms4 ms≈ 5 kat
AlgoritmaEn iyiOrtalamaEn kötü
Baloncuknn²n²
Seçerekn²n²n²
Eklemenn²n²
Hızlın log nn log nn²

Bu dördü dışında da sıralama algoritmaları var: yığınlama sıralaması (heap sort), sayarak sıralama (counting sort), taban sıralaması (radix sort), birleştirmeli sıralama (merge sort) ve şakayla karışık bogosort (rastgele karıştırıp sıralı mı diye bakar). Hangisinin seçileceği sıralanacak veriye bağlıdır.

Kendini test et!

Cevabı görmek için soruya dokun.

  1. 1.5 2 4 1 dizisine baloncuk sıralamanın ilk turu uygulanınca dizi ne olur?

    ✓ 2 4 1 5. 5 her karşılaştırmada sağa geçip sona yerleşir.

  2. 2.5 2 4 1 dizisine seçerek sıralamanın ilk adımı uygulanınca dizi ne olur?

    ✓ 1 2 4 5. En küçük eleman 1 seçilip baştaki 5 ile yer değiştirir.

  3. 3.Ekleme sıralamada, iç döngüdeki karşılaştırmada büyük elemanlar ne yapılır?

    ✓ Bir sağa kaydırılır; böylece açılan boşluğa sıradaki eleman yerleştirilir.

  4. 4.Hızlı sıralamada pivottan küçük hiç eleman yoksa ne olur?

    ✓ Sol grup oluşmaz; algoritma yalnızca pivottan büyük elemanlarla devam eder.

  5. 5.Neden sıralama algoritmaları rastgele sayılarla test edilir?

    ✓ Sıralı veri algoritmanın gerçek işini göstermez; sırasız veriyle hangi algoritmanın ne kadar uğraştığı görülür.

  6. 6.Eleman sayısı 10 kat artınca seçerek sıralamanın süresi yaklaşık kaç kat artar? Neden?

    ✓ Yaklaşık 100 kat, çünkü karmaşıklığı O(n²): 10² = 100.

Deneme testi

Sınavda çıkabilecek türden 10 soru. Bir şık seç; doğru cevap ve açıklaması hemen çıkar.

  1. 1.Küçükten büyüğe sıralarken yan yana duran elemanları ikişer ikişer karşılaştıran ve her turda en büyük elemanı listenin sonuna taşıyan algoritma hangisidir?

  2. 2.6 9 2 8 4 dizisine seçerek sıralamanın ilk adımı uygulanırsa dizi nasıl görünür?

  3. 3.Hızlı sıralama algoritmasının ortalama durumdaki zaman karmaşıklığı nedir?

  4. 4.5 2 7 1 dizisi ekleme sıralama ile sıralanıyor. Son eleman olan 1 yerine yerleştirilmeden hemen önce dizi nasıl görünür?

  5. 5.Seçerek sıralama için aşağıdakilerden hangisi doğrudur?

  6. 6.O(n²) karmaşıklığa sahip bir sıralama algoritmasında eleman sayısı 10 katına çıkarılırsa çalışma süresi yaklaşık kaç katına çıkar?

  7. 7.Ünitedeki hızlı sıralama kodunda pivot olarak hangi eleman seçilir?

  8. 8.Sıralama kodlarında iki elemanın yerini değiştirirken temp değişkeni ne işe yarar?

  9. 9.En iyi, ortalama ve en kötü durumda zaman karmaşıklığı aynı (n²) olan algoritma hangisidir?

  10. 10.Sıralama algoritmaları test edilirken dizinin rastgele sayılarla doldurulmasının amacı nedir?

Sınıf grubuna gönder:WhatsApp'ta paylaş

Bu not ders kitabının yerine geçmez; konu kendi cümlelerimizle, yapay zekâ desteğiyle özetlendi.