Merge Sort (Birleştirmeli Sıralama) Algoritması

Selamün Aleyküm Arkadaşlar;

Merge Sort algoritması parçala (böl) ve yönet tekniğiyle yapılır. İlk önce dizi iki parçaya bölünür. Diğer parçalar kendi aralarında bölünür. Her parçadan bir tane kalana kadar bölünürler.

Elimizde şu şekilde bir dizimiz olsun.

SnapCrab_No-0041

 

Dizi son 1 elemanı kalana kadar kendi arasında ikiye bölünür.

SnapCrab_No-0042

 

Sonra bölünen kısımlar kendi aralarında sıralanarak birleştirilir.

SnapCrab_No-0043

 

Ve böylece dizimiz sıralanmış olur. Bu işlemi koda dökelim.

Burada özyineleme işlemi vardır. Her parça kendi arasında hep ikiye bölünmektedir. Bunun için recursive fonksiyon olarak yazalım. Dizimiz bölünerek sağ ve sol olarak iki diziye ayrılmaktadır.Bu sağ ve sol dizide bir eleman kalana kadar bölünmeye devam etmektedir.

int[] Merge_Sort(int[] d)
{
	//Dizi boyutu 2'den küçükse yani 1 olmuş geriye diziyi döndür.
	if (d.Length < 2)
    	return d;

    int bol = d.Length / 2;

    //Sol ve sağ kısımların tanımlanması
    int[] sol = new int[bol];
    int[] sag = new int[d.Length - bol];

    //Sol diziyi doldur
    for (int i = 0; i < bol; i++){
        sol[i] = d[i];
    }

    //Sağ diziyi doldur
    int k = 0;
    for (int i = bol; i < d.Length; i++){
        sag[k] = d[i];
        k++;
    }

    //Sağ ve sol dizileri parçala
    sol = Merge_Sort(sol);
    sag = Merge_Sort(sag);
}

Parçalanan kısımların kendi aralarında sıralanıp birleştirme işleminin yapılması gerekir. Bunun içinde Birlestir adında bir fonksiyon yazalım. Gelen iki parça kendi aralarında karşılaştırılacak ve birleştirilecek. Bu işlemde bakılmayan elemanlar dizinin sonuna eklenecektir.

int[] birlestir(int[] sol, int[] sag) {
	//Birleştirilen dizi iki dizinin toplam boyutunda olmalı
	int[] a = new int[sol.Length + sag.Length];

    //Sol dizi için j index sayacı, Sağ dizi için i index sayacı, a dizisi için k index sayacı tanımlanmıştır.
    int i = 0, j = 0, k = 0;

    //İki diziyi karşılaştır. Küçük olan elemanları a dizisine ekle eklenen dizilerin indexlerini 1 arttır.
    while (j < sol.Length && i < sag.Length)
        a[k++] = (sag[i] < sol[j])? sag[i++] : sol[j++];

    //Sağ dizisinde eleman kaldıysa a dizisinin sonuna ekle
    while (i < sag.Length)
        a[k++] = sag[i++];

    //Sol dizisinde eleman kaldıysa a dizisinin sonuna ekle
    while (j < sol.Length)
        a[k++] = sol[j++];

    //Sıralanan ve birleştirilen diziyi geri döndür
    return a;
}

Birleştirme işlemi için fonksiyonumuzu yazdık şimdi bu fonksiyonumuzu Merge_Sort fonksiyonunda çağıralım.

int[] Merge_Sort(int[] d)
{
	//Dizi boyutu 2'den küçükse yani 1 olmuş geriye diziyi döndür.
	if (d.Length < 2)
    	return d;

    int bol = d.Length / 2;

    //Sol ve sağ kısımların tanımlanması
    int[] sol = new int[bol];
    int[] sag = new int[d.Length - bol];

    //Sol diziyi doldur
    for (int i = 0; i < bol; i++){
        sol[i] = d[i];
    }

    //Sağ diziyi doldur
    int k = 0;
    for (int i = bol; i < d.Length; i++){
        sag[k] = d[i];
        k++;
    }

    //Sağ ve sol dizileri parçala
    sol = Merge_Sort(sol);
    sag = Merge_Sort(sag);

    //Parçaları sırala ve birleştir ve sıralanan diziyi geri döndür
    return birlestir(sol, sag);
}

Artık Merge_Sort fonksiyonumuzu çağırarak sıralama işlemini yaptırabiliriz.

int[] d = Merge_Sort(new int[]{10, 5, 1, 2, 20, 15});

for (int i = 0; i < d.Length; i++){
    Console.Write(d[i] + " ");
}

Proje dosyasını buradan indirebilirsiniz. (Büyükten küçüğe doğru sıralama yapar.)

PHP

$d = Merge_Sort(array(10, 5, 1, 2, 20, 15));

for ($i=0; $i < count($d); $i++) { 
    echo $d[$i] . ' ';
}

function Merge_Sort($d = array())
{
	//Dizi boyutu 2'den küçükse yani 1 olmuş geriye diziyi döndür.
	if (count($d) < 2)
    	return $d;

    //Tek sayıysa 1 fazlasını al
    $n = 0;
    if(count($d) % 2 == 1)
        $n = count($d) + 1;
    else
        $n = count($d);

    $bol = $n / 2;

    //Sol ve sağ kısımların tanımlanması
    $sol = array();
    $sag = array();

    //Sol diziyi doldur
    for ($i = 0; $i < $bol; $i++){
        $sol[$i] = $d[$i];
    }

    //Sağ diziyi doldur
    $k = 0;
    for ($i = $bol; $i < count($d); $i++){
        $sag[$k] = $d[$i];
        $k++;
    }

    //Sağ ve sol dizileri parçala
    $sol = Merge_Sort($sol);
    $sag = Merge_Sort($sag);

    //Parçaları sırala ve birleştir ve sıralanan diziyi geri döndür
    return birlestir($sol, $sag);
}

function birlestir($sol, $sag) {
	//Birleştirilen dizi iki dizinin toplam boyutunda olmalı
	$a = array();

    //Sol dizi için j index sayacı, Sağ dizi için i index sayacı, a dizisi için k index sayacı tanımlanmıştır.
    $i = 0; $j = 0; $k = 0;

    //İki diziyi karşılaştır. Küçük olan elemanları a dizisine ekle eklenen dizilerin indexlerini 1 arttır.
    while ($j < count($sol) && $i < count($sag))
        $a[$k++] = ($sag[$i] < $sol[$j])? $sag[$i++] : $sol[$j++];

    //Sağ dizisinde eleman kaldıysa a dizisinin sonuna ekle
    while ($i < count($sag))
        $a[$k++] = $sag[$i++];

    //Sol dizisinde eleman kaldıysa a dizisinin sonuna ekle
    while ($j < count($sol))
        $a[$k++] = $sol[$j++];

    //Sıralanan ve birleştirilen diziyi geri döndür
    return $a;
}

 

Hayırlı günler, sağlıcakla kalın.

Bu döküman www.ibasoglu.com’a aittir. Kaynak belirtmek suretiyle alıntı yapılabilir.