Sıralama Algoritmaları

Sayarak sıralama

Sayarak sıralama bilgisayar bilimlerinde kullanılan ve kova sıralaması gibi sıralanacak dizinin içindeki değerlerin aralığının bilinmesi durumunda kullanılabilen bir sıralama algoritmasıdır. Sayarak sıralama algoritması dizideki değerlerin aralık bilgilerini yeni bir dizi oluşturmak için kullanır. Oluşturulan yeni dizinin her bir satırı ana dizide o satır numarasının değerine sahip öğelerin sayısını gösterir. Yeni dizideki öğe değeri sayıları daha sonra ana dizideki tüm değerlerin doğru konuma konulması için kullanılır. Sayarak sıralama algoritması güvercin yuvası sıralamasından daha verimsiz bir algoritmadır.

C++ ile uygulaması


Aşağıdaki program sayarak sıralama algoritmasının C++ dilinde yazılmış bir uygulamasını göstermektedir.

/// countingSort - değerleri tutan bir diziyi sıralamak için.
///
/// Algoritmanın verimli çalışması için sıralacak
/// değerlerin aralığı sıralanacak öğelerin sayısından
/// çok daha büyük olmamalıdır.
///
/// param nums - girdi - sıralanacak değerler dizisi
/// param size - girdi - dizideki öğelerin sayısı
///
void counting_sort(int *nums, int size)
{
// search for the minimum and maximum values in the input
int i, min = nums[0], max = min;
for(i = 1; i < size; ++i)
{
if (nums < min)
min = nums;
else if (nums > max)
max = nums;
}

// create a counting array, counts, with a member for
// each possible discrete value in the input.
// initialize all counts to 0.
int distinct_element_count = max - min + 1;
int[] counts = new int[distinct_element_count];
for(i=0; i<distinct_element_count; ++i)
counts = 0;

// accumulate the counts - the result is that counts will hold
// the offset into the sorted array for the value associated with that index
for(i=0; i<size; ++i)
++counts[ nums - min ];

// store the elements in the array
int j=0;
for(i=min; i<=max; i++)
for(int z=0; z<counts[i-min]; z++)
nums[j++] = i;

delete[] counts;
 
Saçma sıralama

Saçma sıralama (ya da rastgele sıralama) bilgisayar bilimlerinde yalnızca eğitim amaçlı olarak kullanılan verimsiz bir sıralama algoritmasıdır. Bir deste oyun kağıdı saçma sıralama algoritmasıyla sıralanmak istendiğinde, destenin sıralı olup olmadığına bakılır, eğer deste sıralı değilse havaya atılarak yere düşen kartlar toplanarak deste yeniden oluşturulur. Bu işlem deste sıralanana kadar sürer.


Uygulama

Sözde kodu:


while not InOrder(deck) do Shuffle(deck);

Java
public int[] BogoSort(int[] numbers)
{
Random rnd = new Random();
while(true)
{
boolean sorted = true;
for(int i = 0; i < numbers.length-1; i++)
if(numbers > numbers[i+1])
sorted = false;
if (sorted)
return numbers;
for(int i = numbers.length - 1; i > 0; i--)
{
int rand = rnd.nextInt(i);
int temp = numbers;
numbers = numbers[rand];
numbers[rand] = temp;
}
}
}

Benzer algoritmalar

Rastgele değiştirmeli sıralama


Rastgele değiştirmeli sıralama, rastgele sayı seçmeye dayalı, saçma sıralamaya benzer bir sıralama algoritmasıdır. Eğer sıralanacak dizi sıralı değilse algoritma rastgele iki sayı seçer ve bu iki sayıyı birbiriyle değiştirir. Algoritmanın çalışma süresini belirlemek oldukça zordur ve gerçek uygulamalarında sıralanmış bir diziye ulaşamayabilir.
 
Seçmeli Sıralama

Seçmeli Sıralama, bilgisayar bilimlerinde kullanılan karmaşıklığı bir sıralama algoritmasıdır. Karmaşıklığı
04a727b4c56b63e9130a2e8a42eb9038.png
olduğu için büyük listeler üzerinde kullanıldığında verim sağlamaz ve genel olarak benzeri olan eklemeli sıralamadan daha başarısızdır. Seçmeli sıralama yalın olduğu ve bazı durumlarda daha karmaşık olan algoritmalardan daha iyi sonuç verdiği için tercih edilebilir.
Selection_sort_animation.gif

Seçmeli sıralama algoritması​

Selection-Sort-Animation.gif

Seçmeli Sıralama'nın nasıl çalıştığını gösteren görüntü

Yöntem
Seçmeli Sıralama'nın nasıl çalıştığını gösteren görüntü

Algoritma aşağıdaki gibi çalışır:

Listedeki en küçük değerli öğeyi bul.
İlk konumdaki öğeyle bulunan en küçük değerli öğenin yerini değiştir.
Yukarıdaki adımları listenin ilk elemanından sonrası için (ikinci elemandan başlayarak) yinele.

Sözde Kodu


A sıralanacak öğeler kümesi, n ise A'daki öğe sayısıdır. Dizi 0 numaralı dizinle başlamaktadır.

for i ← 0 to n-2 do
min ← i
for j ← (i + 1) to n-1 do
if A[j] < A[min]
min ← j
swap A and A[min]


Seçmeli Sıralama Algoritmasının Örnek Kodu


public int[] secmeliSiralama(int[] dizi)
{
int enkucuk, yedek;
for (int i = 0; i < dizi.Length - 1; i++)
{
enkucuk = i;
for (int j = i + 1; j < dizi.Length; j++)
if (dizi[j] < dizi[enkucuk])
enkucuk = j;
if (enkucuk != i)
{
yedek = dizi;
dizi = dizi[enkucuk];
dizi[enkucuk] = yedek;
}
}
return dizi;


Selection_Sort_-_%C5%9Eekil.jpg

6 elemanlı içeriği karışık olarak verilmiş bir bir sayı dizisinin Seçmeli Sıralama algoritması kullanılarak nasıl küçükten-büyüğe doğru sıralandığını göstermektedir. 1. adımda dizinin ilk elemanı (6) alınır. Bu eleman diğer 5 eleman ile karşılaştırılır. Eğer bulunan eleman(1) ilk elemandan küçükse 1.elman ile yer değiştirilir. 2. adımda dizinin ikinci elemanı(3) alınır. Bu eleman kalan 4 eleman ile karşılaştırılır. Eğer bulunan eleman(2) ikinci elemandan küçükse 2. eleman ile yer değiştirilir ve bu işlem dizi sonuna kadar devam eder. Böylelikle dizi küçükten-büyüğe sıralanmış olur.
 
Sıralama


Sıralama bir dizi elemanı, belirli bir özelliğine göre sıraya dizme işlemine verilen addır. Bilgisayar bilimlerinin en çok incelenmiş konularından birisi sıralama algoritmalarıdır.

Karışık halde: 9 4 2 8 3 1 5 6 7
Sıraya dizilmiş: 1 2 3 4 5 6 7 8 9

Sıralama, genellikle indekslerde, ansiklopedilerde kullanılır. Ayrıca şuralarda da yaygındır: Katalog, bibliyografya, sözlük, kütüphane fişleri, ve bazı arama motorları.





Tarrak Sıralaması
Tarrak Sıralaması, ilk defa 1991 yılının Nisan ayında Stephen Lacey ve Richard Box tarafından Byte dergisinde duyurulmuş yalın bir sıralama algoritmasıdır. Kendisinden önce duyurulmuş kabarcık sıralaması algoritmasından başarılıdır ve karmaşıklıkta hızlı sıralama algoritmasıyla yarışır. Algoritmanın ana fikri listenin sonundaki küçük değerli öğelerin sayısını azaltmaktır. Kabarcık sıralaması algoritmasında sıralanacak listenin sonundaki küçük değerli öğelerin varlığı algoritmayı çok yavaşlattığı için tarak sıralamasında bu değerlerin sayısının azaltılması yoluna gidilmiştir.

Kabarcık sıralaması algoritmasında iki öğe karşılaştırıldığında aralarındaki mesafe her zaman 1'dir. Başka bir deyişle, kabarcık sıralaması her zaman ardışık iki değeri karşılaştırır. Taraf sıralaması ise bunun aksine aralarındaki mesafe birden çok daha fazla olan öğeleri karşılaştırabilir. (Kabuk sıralaması da aynı düşünceyle tasarlanmıştır ancak kabuk sıralaması kabarcık sıralamasının değil seçmeli sıralamanın bir türevidir.)

Sözde Kodu

function combsort11(array input)
gap := input.size //öğeler arasındaki aralığın başlangıç boyutunu belirle

loop until gap <= 1 or swaps = 0
//yeni bir tarama için aralığın boyutunu güncelle
if gap > 1
gap := gap / 1.3
if gap = 10 or gap = 9
gap := 11
end if
end if

i := 0
swaps := 0 // Açıklama için kabarcık sıralamasına bakınız

// giriş listesinin üzerinden tek bir "tarama"
loop until i + gap >= array.size //Benzer yaklaşım için kabuk sıralamasına bakınız
if array > array[i+gap]
swap(array, array[i+gap])
swaps := 1 // Aritmetik taşma düzeltmesi için
end if
i := i + 1
end loop

end loop
end function
 
Yığın Sıralaması

(İngilizcesi: Heapsort), bilgisayar bilimlerinde kullanılan karşılaştırmaya dayalı bir sıralama algoritmasıdır. Uygulamada pek çok bilgisayarda hızlı sıralama algoritmasından daha yavaş çalışsa da en kötü durumda O(n log n) çalışma süresi vardır. Yığın sıralaması diziyi yerinde sıralar ancak kararlı bir sıralama algoritması değildir.

Sözde Kodu

Aşağıda yığın sıralaması algoritmasının sözde kodu verilmiştir. swap dizideki iki öğenin yerlerini değiştirmek için kullanılmaktadır.

function heapSort(a, count) is
input: an unordered array a of length count

(first place a in max-heap order)
heapify(a, count)

end := count - 1
while end > 0 do
(swap the root(maximum value) of the heap with the last element of the heap)
swap(a[end], a[0])
(decrease the size of the heap by one so that the previous max value will
stay in its proper placement)
end := end - 1
(put the heap back in max-heap order)
siftDown(a, 0, end)

function heapify(a,count) is
(start is assigned the index in a of the last parent node)
start := (count - 1) / 2

while start ≥ 0 do
(sift down the node at index start to the proper place such that all nodes below
the start index are in heap order)
siftDown(a, start, count-1)
start := start - 1
(after sifting down the root all nodes/elements are in heap order)

function siftDown(a, start, end) is
input: end represents the limit of how far down the heap
to sift.
root := start

while root * 2 + 1 ≤ end do (While the root has at least one child)
child := root * 2 + 1 (root*2+1 points to the left child)
(If the child has a sibling and the child's value is less than its sibling's...)
if child < end and a[child] < a[child + 1] then
child := child + 1 (... then point to the right child instead)
if a[root] < a[child] then (out of max-heap order)
swap(a[root], a[child])
root := child (repeat to continue sifting down the child now)
else
return

heapify fonksiyonu alttan üste doğru bir yığın oluşturmak için kullanılırken yığın özelliği kazandırılmak için öğeler aşağıya doğru incelenir. Aşağıda gösterilmiş bir diğer yol kullanılarak yığın üstten alta oluşturulup öğeler yukarı doğru incelenebilir. Ancak aşağıdaki uygulama her ne kadar anlaşılması daha kolay olsa da daha yavaştır.

function heapify(a,count) is
(end is assigned the index of the first (left) child of the root)
end := 1

while end < count
(sift up the node at index end to the proper place such that all nodes above
the end index are in heap order)
siftUp(a, 0, end)
end := end + 1
(after sifting up the last node all nodes are in heap order)

function siftUp(a, start, end) is
input: start represents the limit of how far up the heap to sift.
end is the node to sift up.
child := end
while child > start
parent := ⌊(child - 1) ÷ 2⌋
if a[parent] < a[child] then (out of max-heap order)
swap(a[parent], a[child])
child := parent (repeat to continue sifting up the parent now)
else
return
 
İplik sıralaması
(İngilizcesi: Strand sort) bilgisayar bilimlerinde kullanılan bir sıralama algoritmasıdır. Sıralanacak olan dizinin, sıralanmış alt dizilerinin oluşturularak bu alt dizilerin birleştirilmesi yoluyla sonucun oluşturulması mantığına dayanır. Algoritmanın her bir aşamasında ana dizinin üzerinden geçilir ve bu diziden zaten sıralanmış olan bir dizi eleman çıkarılır. Çıkarılan bu eleman dizileri daha sonra birleştirilir.

Algoritmanın adı, sıralanacak dizinin içinden çıkan kendi içinde sıralanmış alt dizilerin ipliklere benzetilmesinden gelmektedir. İplik sıralaması algoritması, ana diziden ipleri çıkarırken ve oluşan sıralı ipleri birleştirirken karşılaştırma kullandığı için bir karşılaştırma sıralamasıdır.

İplik sıralaması algoritmasının karmaşıklığı ortalamada O(n log n)'dir. Sıralanacak dizinin zaten sıralı olduğu en iyi durumda algoritmanın karmaşıklığı O(n), sıralanacak dizinin tersten sıralı olduğu en kötü durumda ise algoritmanın karmaşıklığı O(n2)'dir.


Örnek


Sıralanacak dizinin üzerinden bir kere geçilir ve yükselen (sıralı) sayılar alınır.
Sıralı olan alt dizi ilk yinelemenin ardından boş olan sıralanmış dizinin üstüne konur.
Ana dizinin üzerinden yeniden geçilir ve kendi içinde sıralı yeni bir alt dizi çıkarılır.
Artık sıralanmış dizi boş olmadığından yeni çıkarılan alt dizi sıralanmış diziyle birleştirilir.
Alt dizi ve ana dizi boşalana kadar 3 ve 4üncü adımlar yinelenir.

Sıralanmamış dizi Alt dizi Sıralanmış dizi
3 1 5 4 2
1 4 2 3 5
1 4 2 3 5
2 1 4 3 5
2 1 3 4 5
2 1 3 4 5
1 2 3 4 5

Sözde Kodu

İplik sıralamasının yalın bir sözde kodu aşağıda verilmiştir:

procedure strandSort( A : list of sortable items ) defined as:
while length( A ) > 0
clear sublist
sublist[ 0 ] := A[ 0 ]
remove A[ 0 ]
for each i in 0 to length( A ) do:
if A[ i ] > sublist[ last ] then
append A[ i ] to sublist
remove A[ i ]
end if
end for
merge sublist into results
end while
return results
end procedure

Uygulama Örnekleri

C# ile uygulama



Aşağıdaki program iplik sıralamasının C# kullanılarak oluşturulmuş bir uygulamasıdır:

public static LinkedList<int> sort(LinkedList<int> array) {
LinkedList<int> results = new LinkedList<int>();
LinkedList<int> sublist = new LinkedList<int>();
while (array.Count != 0)
{
sublist.Clear();
sublist.AddLast(array.First.Value);
array.RemoveFirst();
LinkedListNode<int> i = array.First;
while (i != null)
{
if(i.Value >= sublist.Last.Value)
{
sublist.AddLast(i.Value);
LinkedListNode<int> temp = i;
i = i.Next;
array.Remove(temp);
}
else
{
i = i.Next;
}
}

i = results.First;
while (sublist.Count != 0)
{
if (i == null)
{
results.AddLast(sublist.First.Value);
sublist.RemoveFirst();
}
else if (sublist.First.Value < i.Value)
{
results.AddBefore(i, sublist.First.Value);
sublist.RemoveFirst();
}
else
{
i = i.Next;
}
}
}
return results;
}
Java ile uygulama

Aşağıdaki program iplik sıralamasının Java kullanılarak oluşturulmuş bir uygulamasıdır:

public static <E extends Comparable<? super E>> List<E> sort(Collection<E> coll) {
List<E> results = new LinkedList<E>();

while (!coll.isEmpty())
{
LinkedList<E> sublist = new LinkedList<E>();
Iterator<E> i = coll.iterator();
sublist.addLast(i.next());
while (i.hasNext())
{
E val = i.next();
if (val.compareTo(sublist.getLast()) >= 0)
{
sublist.addLast(val);
i.remove();
}
}

if (!results.isEmpty())
{
ListIterator<E> li = results.listIterator();
E current = li.next();
while (!sublist.isEmpty())
{
if (sublist.getFirst().compareTo(current) < 0)
li.add(sublist.removeFirst());
else if (li.hasNext())
current = li.next();
else
break;
}
}
results.addAll(sublist);
}
return results;
}
 
İçgözlemle sıralama

İçgözlemle sıralama 1997 yılında David Musser tarafından tasarlanmış bir sıralama algoritmasıdır. Algoritma verilen bir diziyi sıralamaya hızlı sıralama algoritmasıyla başlar ancak özyineleme derinliği önceden belirlenen bir değeri aştığında yığın sıralamasına döner. İki algoritmanın iyi yönlerini birleştiren içgözlemle sıralama algoritmasının karmaşıklığı en kötü durumda O(n log n)'dir. Olağan veri yükleri üzerinde kullanıldığında başarımı hızlı sıralamanın başarımına yakındır. Kullandığı iki algoritma karşılaştırma ile sıraladığından içgözlemle sıralama da karşılaştırma ile sıralayan bir algoritma olarak sınıflandırılır.
 
İçgözlemle sıralama

İçgözlemle sıralama 1997 yılında David Musser tarafından tasarlanmış bir sıralama algoritmasıdır. Algoritma verilen bir diziyi sıralamaya hızlı sıralama algoritmasıyla başlar ancak özyineleme derinliği önceden belirlenen bir değeri aştığında yığın sıralamasına döner. İki algoritmanın iyi yönlerini birleştiren içgözlemle sıralama algoritmasının karmaşıklığı en kötü durumda O(n log n)'dir. Olağan veri yükleri üzerinde kullanıldığında başarımı hızlı sıralamanın başarımına yakındır. Kullandığı iki algoritma karşılaştırma ile sıraladığından içgözlemle sıralama da karşılaştırma ile sıralayan bir algoritma olarak sınıflandırılır.
 
Geri
Top