Final dönemi nedeniyle verilen zorunlu ve uzun bir aradan sonra C’de pointer aritmetiği üzerine başlattığım yazı dizisine sıralama algoritmaları ile devam ediyorum.
Bu konuya ilişkin geçmiş paylaşımlardan yola çıkarak pointer aritmetiğinin mantığını genel olarak kavradığımızı umuyorum. Bu nedenle işin pointer kısmına doğrudan kod üzerinde değineceğim. Şimdi sıralama algoritması nedir, bunu inceleyelim..
Arama algoritmalarında olduğu gibi, eğer işimiz veri yapılarıyla ise vazgeçilmezimiz olacak algoritmalardan bir diğeri de sıralama algoritmalarıdır. Adından da anlaşılacağı gibi bir veri yapısı üzerindeki elemanların belirlenen bir kritere göre dizilmesini sağlayan algoritmalardır.
“Her sıralama algoritmasının içinde bir arama algoritması yatar..” desek yalan söylemiş olmayız sanırım. Bulduğun değeri başka bir değerle karşılaştırma işlemi, her iki algoritmada da mevcut ne de olsa..
Özetle sıralama algoritmalarıyla yapacağımız işlemlerin edebiyatı şu;
- Bir adet gezicimiz, bir adet de kontrolcümüz olacak.
- Gezici veriyapısını dolaşıp bize sıralama kriterine ait verileri getirecek,
- Biz de bu verileri kontrolcümüzdeki verilerle kıyaslayıp ya “direct pass” ya da “change and pass” işlemi yapacağız.
“direct pass” ve “change and pass” nedir ?
Kontrolcümüz, veriyapısındaki elemanları tek tek gezerken, gezicimiz ise, kontrolcünün aldığı her değer için tüm elemanları gezer.
Kontrolcünün ve gezicinin sahip olduğu değerler kıyaslandıktan sonra, elde edilen sonuca göre;
- Ya kontrolcüdeki değer ile gezicideki değer değiştirilir ve bir sonraki elemana geçilir (change and pass),
- Ya da değerler üzerinde bir değişiklik yapılmadan doğrudan bir sonraki elemana geçilir (direct pass).
Bu yazı için, “Bubble Sort” (Kabarcık sıralama) algoritmasını kullanacağız.
Bubble Sort Nedir ? Neyi Nasıl yapar ?
Aslında Bubble Sort, aynen adında geçen işlemi gerçekleştirir. Veri yapısı üzerindeki elemanlar, birbirleri arasında yer değiştirerek kaya kaya olmaları gereken yere gelirler. Tıpkı bir kabarcığın suyun yüzeyine çıkması gibi..
Şimdi pointer aritmetiği kullanmadan bir bubble sort algoritması gerçekleştirelim…
<h1>include <stdio.h></h1> <h1>include <stdlib.h></h1> void yazdir(int []); int main() { int dizi[] = {7,3,5,2,4,8,6,1}; int gezici,kontrolcu,temp; <pre><code>printf("Siralanmadan once:\n\n"); yazdir(dizi); for(kontrolcu=0; kontrolcu<8; kontrolcu++)//Kontrolcümüz diziyi geziyor... { for(gezici=kontrolcu; gezici<8; gezici++)//Kontrolcümüzün her değişimi için, gezici sonraki tüm elemanları geziyor... { if(dizi[kontrolcu] > dizi[gezici])//Eğer kontrolcü daha büyük bir değer taşıyorsa, bu değeri gezicideki değer ile değiştiriyor... { temp = dizi[kontrolcu]; dizi[kontrolcu] = dizi[gezici]; dizi[gezici] = temp; } } } printf("\n\n\n"); printf("Siralandiktan sonra:\n\n"); yazdir(dizi); printf("\n\n\n"); return 0;</code></pre> } void yazdir(int dizi[]) //Yazdırma fonksiyonu… { int i; for(i=0; i<8; i++) { printf("%d ",dizi[i]); }
Böylelikle Bubble Sort algoritmasını C dilinde implemente etmiş olduk. Artık bubble sort’un nasıl işlediğini bildiğimize göre, fonksiyonu pointer aritmetiği kullanacak şekilde yeniden düzenleyebiliriz..
<h1>include <stdio.h></h1> <h1>include <stdlib.h></h1> void yazdir(int []); void karsilastir(int *,int *); int main() { int dizi[] = {7,3,5,2,4,8,6,1}; int gezici,kontrolcu; int <em>deger_1,</em>deger_2; <pre><code>printf("Siralanmadan once:\n\n"); yazdir(dizi); for(kontrolcu=0; kontrolcu<8; kontrolcu++)//Kontrolcümüz diziyi geziyor... { for(gezici=kontrolcu; gezici<8; gezici++)//Kontrolcümüzün her değişimi için, gezici sonraki tüm elemanları geziyor... { deger_1 = &dizi[kontrolcu]; deger_2 = &dizi[gezici]; karsilastir(deger_1,deger_2);//Pointerlar, karsilastirma ve gerekirse degistirme islemi yapacak olan fonksiyona gönderiliyor... } } printf("\n\n\n"); printf("Siralandiktan sonra:\n\n"); yazdir(dizi); printf("\n\n\n"); return 0;</code></pre> } void karsilastir(int *deger_1,int *deger_2) { int temp; if(*deger_1 > *deger_2)//Ayni karsilastirma islemi bu kez pointerlar ile yapiliyor… { temp = *deger_1; *deger_1 = *deger_2; *deger_2 = temp; } //Pointer ile yapilan islemler degeri dogrudan degistirdigi icin, fonksiyonun bir parametre dondurmesine gerek kalmadi… } void yazdir(int dizi[]) //Yazdırma fonksiyonu… { int i; for(i=0; i<8; i++) { printf("%d ",dizi[i]); } }
Böylelikle Bubble Sort işlemini pointer aritmetiği ile de gerçekleştirmiş olduk.
Neden ilk örnekte görülen yapı yerine, pointer aritmetiği yapısını kullanırız ?
İkinci örnek incelendiğinde, ilk örnekten farklı olarak karşılaştırma işleminin bir fonksiyona aktarıldığı görülmüştür. Parametre olarak aktarılacak değişken türleri içerisinde en az boyutlu olan pointerlardır. Bu nedenle büyük boyutlu veri yapıları ile işlem yapılacağı zaman, tüm veri yapısını fonksiyona aktarmaktansa veri yapısını temsil eden pointerı aktarmayı yeğleriz..
Bir sonraki yazıda : Pointer aritmetiği, ilkel yapay zeka ve basit veri yapıları kullanarak labirent oyunu yaratma…