Yığın Sıralama Algoritması (Kod İçerisinde) Python ve C++)

Yığın Sıralama Algoritması Nedir?

Heap Sort, popüler ve daha hızlı sıralama algoritmalarından biridir. Tam ikili ağaç veri yapısı üzerine inşa edilmiştir. Maksimum öğeyi arayacağız ve maksimum yığın için onu en üste koyacağız. Bunu ikili ağacın ana düğümüne koyacağız.

Diyelim ki bir dizi verildi, veri = [10,5, 7, 9, 4, 11, 45, 17, 60].

Dizide, eğer i-th (i=0,1,2,3 …) indeksi bir ebeveyn düğüm ise, o zaman (2i+1) ve (2i+2) sol ve sağ çocukları olacaktır. Bu diziyle tam bir ikili ağaç oluşturmak şöyle görünecektir:

Yığın Sıralama Algoritması

Dizinin başından sonuna kadar yığınlaştırma işlemini yapacağız. Başlangıçta, diziyi bir ağaca dönüştürürsek yukarıdaki gibi görünecektir. Herhangi bir yığın özelliğini (min-yığın veya max yığın) korumadığını görebiliriz. Tüm düğümler için yığınlaştırma işlemini yaparak sıralanmış diziyi elde edeceğiz.

Yığın Sıralamanın Uygulanması

Yığın sıralama algoritmasının bazı kullanımları aşağıda verilmiştir:

  • “Öncelik Kuyruklarının” oluşturulması yığın sıralamasını gerektirir. Çünkü yığın sıralaması, her ekleme yapıldıktan sonra öğeyi sıralanmış halde tutar.
  • Yığın Veri Yapısı k'yı bulmada etkilidirth Belirli bir dizideki en büyük öğe.
  • Linux Çekirdeği yığın sıralamasını varsayılan olarak kullanır sıralama algoritması çünkü O (1) uzay karmaşıklığına sahiptir.

Örnekle Yığın Sıralaması Oluşturun

Burada, aşağıdaki tamamlanmış ikili ağaçtan bir maksimum yığın oluşturacağız.

Örnekle Yığın Sıralaması Oluşturun

Yaprak düğümleri 17, 60, 4, 11 ve 45'tir. Hiçbir alt düğümleri yoktur. Bu yüzden yaprak düğümlerdir. Bu yüzden, heapify yöntemini üst düğümlerinden başlatacağız. İşte adımlar:

) 1 Adım En soldaki alt ağacı seçin. Alt düğümler daha büyükse ana düğümü alt düğümle değiştirin.

Burada ana düğüm 9'dur. Alt düğümler ise 17 ve 60'tır. 60 en büyüğü olduğundan, 60 ve 9, eşitliği korumak için yer değiştirecektir. maksimum yığın.

Örnekle Yığın Sıralaması Oluşturun

) 2 Adım Şimdi en soldaki alt ağaç yığın halindedir. Bir sonraki ana düğüm 7'dir. Bu ebeveynin iki alt düğümü vardır ve en büyüğü 45'tir. Yani 45 ve 7 yer değiştirecektir.

Örnekle Yığın Sıralaması Oluşturun

Örnekle Yığın Sıralaması Oluşturun

) 3 Adım 60 ve 4 nolu düğümler 5 nolu ana düğüme sahiptir. “5”, 60 nolu alt düğümden daha küçük olduğu için değiştirilecektir.

Örnekle Yığın Sıralaması Oluşturun

Örnekle Yığın Sıralaması Oluşturun

) 4 Adım Artık düğüm 5'in alt düğümü 17,9 var. Bu, max heap özelliğini korumak değildir. Yani 5'in yerine 17 getirilecek.

Örnekle Yığın Sıralaması Oluşturun

) 5 Adım 10.node önce 60 ile, sonra da 17 ile yer değiştirecek. İşlem aşağıdaki gibi olacak.

Örnekle Yığın Sıralaması Oluşturun

Örnekle Yığın Sıralaması Oluşturun

) 6 Adım 5. adıma kadar maksimum yığını oluşturduk. Her ana düğüm, alt düğümlerinden daha büyüktür. Kök düğüm maksimum değere (60) sahiptir.

Not: Sıralanmış diziyi oluşturmak için maksimum değerli düğümü ardılıyla değiştirmemiz gerekir.

Bu işleme “maksimum çıkar”. Maksimum düğüm 60 olduğundan, konumunu 0'ıncı dizine sabitleyeceğiz ve 60 düğümü olmadan yığın oluşturacağız.

Örnekle Yığın Sıralaması Oluşturun

Örnekle Yığın Sıralaması Oluşturun

) 7 Adım 60 çıkarıldığı için bir sonraki maksimum değer 45 olur. 45. düğümden tekrar “Max Çıkarma” işlemini yapacağız.

Bu sefer 45'i alacağız ve kök düğümü halefi 17 ile değiştireceğiz.

gerçekleştirmemiz gerekiyor”Maksimum Çıkarma”tüm öğeler sıralanana kadar.

Tüm maksimum değerleri çıkarana kadar bu adımları uyguladığımızda aşağıdaki diziyi elde edeceğiz.

Örnekle Yığın Sıralaması Oluşturun

İkili Yığın Nedir?

İkili Yığın bir nevi tamdır ikili ağaç veri yapısı. Bu tür ağaç yapısında ana düğüm, alt düğümlerden ya daha büyük ya da daha küçüktür. Ana düğüm daha küçükse yığına "Min Heap" adı verilir ve ana düğüm daha büyükse yığına "Max Heap" adı verilir.

Aşağıda minimum yığın ve maksimum yığın örnekleri verilmiştir.

Min. Yığın ve Maksimum Yığın
Min. Yığın ve Maksimum Yığın

Yukarıdaki şekilde “Min Heap” dikkat ederseniz ana düğüm her zaman alt düğümlerden daha küçüktür. Ağacın başında en küçük değer olan 10’u bulabiliriz.

Benzer şekilde, “Max Heap” için ana düğüm her zaman alt düğümlerden daha büyüktür. “Max Heap” için maksimum eleman baş düğümde mevcuttur.

“Heapify” nedir?

"Heapify", düğümün konumunu garantileyen yığın ilkesidir. Heapify'da, maksimum yığın her zaman ebeveyn ve çocukla bir ilişki sürdürür ve bu ebeveyn düğümü çocuk düğümlerinden daha büyük olacaktır.

Örneğin, yeni bir düğüm eklenirse, yığını yeniden şekillendirmemiz gerekir. Ancak, düğümleri değiştirmemiz veya takas etmemiz veya diziyi yeniden düzenlememiz gerekebilir. Yığının yeniden şekillendirilmesi işlemine "yığınlaştırma" denir.

İşte heapify'ın nasıl çalıştığına dair bir örnek:

Yeni Bir Düğüm Ekleme ve Heapify
Yeni bir düğüm ekleme ve yığınlama

Heapify için adımlar şunlardır:

) 1 Adım Düğüm 65, düğüm 60'ın sağ çocuğu olarak eklendi.

) 2 Adım Yeni eklenen düğümün üst düğümden büyük olup olmadığını kontrol edin.

) 3 Adım Ana düğümden daha büyük olduğu için sağdaki çocuğu ebeveyniyle değiştirdik.

Yığın nasıl inşa edilir

Yığın oluşturmadan veya bir ağacı yığınlaştırmadan önce, onu nasıl depolayacağımızı bilmemiz gerekir. Yığın tam bir ikili ağaç olduğundan, bir dizi yığının verilerini tutmak için.

Diyelim ki bir dizi toplam n eleman içeriyor. Eğer “i” inci indeks bir üst düğümse, o zaman sol düğüm indekste olacaktır (2i+1)ve sağ düğüm dizinde olacak (2i+2). Dizi indeksinin 0'dan başladığını varsayıyoruz.

Bunu kullanarak, maksimum yığını aşağıdaki gibi bir diziye kaydedelim:

Max Heap'in Dizi Tabanlı Gösterimi
Maksimum yığının dizi tabanlı gösterimi

Heapify algoritması heap özelliğini korur. Eğer ebeveyn uç değere sahip değilse (daha küçük veya daha büyük), en uç çocuk düğümüyle takas edilir.

Maksimum yığını yığın haline getirmenin adımları şunlardır:

) 1 Adım Yaprak düğümden başlayın.

) 2 Adım Ebeveyn ve çocuklar arasındaki maksimum değeri bulun.

) 3 Adım Alt düğümün değeri üst düğümden daha büyükse düğümleri değiştirin.

) 4 Adım Bir seviye yukarı çıkın.

) 5 Adım Dizin 2,3,4'a ulaşana veya ağacın tamamını sıralayana kadar 0 adımlarını izleyin.

İşte yinelemeli yığınlaştırma (maksimum yığın) için sözde kod:

def heapify():
  input→ array, size, i
  largest = i
  left = 2*i + 1
  right = 2*i + 2
if left<n and array[largest ] < array[left]:
  largest = left
if right<n and array[largest ] < array[right]:
  largest = right
If largest not equals i:
  swap(array[i],array[largest])
  heapify(array,n,largest)

Yığın Sıralaması için Sahte Kod

Yığın sıralama algoritmasının sözde kodu şöyledir:

Heapify(numbers as an array, n as integer, i as integer):
  largest = i
  left = 2i+1
  right= 2i+2
if(left<=n) and (numbers[i]<numbers[left])
  largest=left
if(right<=n) and (numbers[i]<numbers[right])
  largest=right
if(largest  != i)
  swap(numbers[i], numbers[largest])
  Heapify(numbers,n,largest)
HeapSort(numbers as an array):
  n= numbers.size()
for i in range n/2 to 1
  Heapify(numbers,n,i)
for i in range n to 2
  Swap numbers[i] with numbers[1]
  Heapify(numbers,i,0)

Yığın Sıralama Kodu Örneği C++

#include <iostream>
using namespace std;
void display(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << "\t";
    }
    cout << endl;
}
void heapify(int numbers[], int n, int i)
{
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    if (left < n && numbers[left] < numbers[largest])
    {
        largest = left;
    }
    if (right < n && numbers[right] < numbers[largest])
    {
        largest = right;
    }
    if (largest != i)
    {
	//uncomment the following line to see details in output
        //cout<<"Swapping "<< numbers[i]<< " and "<<numbers[largest]<<endl;
        swap(numbers[i], numbers[largest]);
        heapify(numbers, n, largest);
    }
}
void heapSort(int numbers[], int n)
{
    for (int i = n/2 - 1; i >= 0; i--)
    {
        heapify(numbers, n, i);
//uncomment the following line to see details in output
 //cout<<"Heapify:\t";
  //display(numbers,n);
    }
    for (int i = n - 1; i >= 0; i--)
    {
        swap(numbers[0], numbers[i]);
        heapify(numbers, i, 0);
    }
}
int main()
{
    int numbers[] = { 10,5, 7, 9, 4, 11, 45, 17, 60};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    cout<<"Initial Array:\t";
    display(numbers,size);
    heapSort(numbers, size);
    cout<<"Sorted Array (descending order):\t";
    display(numbers, size);
}

Çıktı:

Initial Array:  10      5       7       9       4       11      45      17      60
Sorted Array (descending order):  60      45      17      11      10      9       7       5       4

Yığın Sıralama Kodu Örneği Python

def display(arr):
    for i in range(len(arr)):
    print(arr[i], end = "\t")
print()
def heapify(numbers, n, i):
    largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and numbers[left] < numbers[largest]:
    largest = left
if right < n and numbers[right] < numbers[largest]:
    largest = right
if largest != i:
    numbers[i], numbers[largest] = numbers[largest], numbers[i]
heapify(numbers, n, largest)
def heapSort(items, n):
    for i in range(n //2,-1,-1):
        heapify(items, n, i) for i in range(n - 1, -1, -1):
        items[0], items[i] = items[i], items[0] heapify(items, i, 0) numbers = [10, 5, 7, 9, 4, 11, 45, 17, 60] print("Initial List:\t", end = "") display(numbers) print("After HeapSort:\t", end = "") heapSort(numbers, len(numbers)) display(numbers)

Çıktı:

Initial List:   10      5       7       9       4       11      45      17      60
After HeapSort: 60      45      17      11      10      9       7       5       4

Heap Sort'un Zaman ve Mekan Karmaşıklık Analizi

Yığın sıralaması için analiz edebileceğimiz Zaman karmaşıklığı ve Uzay karmaşıklığı var. Zaman karmaşıklığı için şu durumlara sahibiz:

  1. En iyi senaryo
  2. Ortalama Vaka
  3. En kötü durumda

Yığın tam bir ikili ağaç üzerinde uygulanır. Yani ikili ağacın alt seviyesinde maksimum sayıda düğüm olacaktır. Alt düzeyde n düğüm varsa, üst düzeyde n/2 düğüm bulunur.

Zaman ve Mekan Karmaşıklığı Analizi

Bu örnekte Düzey 3'te dört öğe, düzey 2'de iki öğe ve düzey 1'de bir öğe bulunmaktadır. Toplam n sayıda öğe varsa, yükseklik veya toplam seviye şu şekilde olacaktır: Giriş2(N). Bu nedenle, tek bir öğenin eklenmesi maksimum Log(n) yineleme gerektirebilir.

Yığından maksimum değeri almak istediğimizde, sadece kök düğümü alırız. Sonra tekrar heapify'ı çalıştırırız. Her heapify Giriş2(N) zaman. Maksimumun çıkarılması O(1) zaman alır.

Yığın Sıralama Algoritması için En İyi Durum Zaman Karmaşıklığı

Dizideki tüm öğeler zaten sıralandığında, yığının oluşturulması O(n) zaman alacaktır. Çünkü liste sıralanırsa bir öğenin eklenmesi O(1) olan sabit süreyi alacaktır.

Bu nedenle, en iyi durumda bir maksimum yığın veya minimum yığın oluşturmak O(n) zaman alacaktır.

Yığın Sıralama Algoritması için Ortalama Durum Zaman Karmaşıklığı

Bir öğeyi eklemek veya maksimum bir değeri çıkarmak O(log(n)) zaman alır. Bu nedenle, yığın sıralama algoritması için ortalama durum zamanı karmaşıklığı O(n log(n)).

Yığın Sıralama Algoritması için En Kötü Durum Zaman Karmaşıklığı

Ortalama duruma benzer şekilde, en kötü senaryoda, n kez yığınlama yapmak zorunda kalabiliriz. Her yığınlama O(log(n)) zamana mal olacaktır. Bu nedenle, en kötü durum zaman karmaşıklığı şu şekilde olacaktır: O(n log(n)).

Yığın Sıralama Algoritması için Uzay Karmaşıklığı

Yığın sıralaması yerinde tasarlanmış bir algoritmadır. Bu, görevi gerçekleştirmek için ekstra veya geçici belleğe ihtiyaç duyulmadığı anlamına gelir. Uygulamayı görürsek, düğümlerin değişimini gerçekleştirmek için swap() kullandığımızı fark edeceğiz. Başka bir liste veya diziye gerek yoktu. Bu nedenle, alan karmaşıklığı O(1)'dir.