Hunniku sortimise algoritm (koos Code in Python ja C++)

โšก Nutikas kokkuvรตte

Hunniku sortimise algoritm sorteerib massiivi, luues binaarkupi ja korrates selle korduvalt.traclisades selle juurvรครคrtuse sorteeritud sektsiooni. See ressurss selgitab heapify, max ja min heap'e, pseudokoodi ja tรคielikku Python ja C++ implementatsioonid ajalise keerukuse analรผรผsiga.

  • ๐ŸŒณ Pรตhiidee: Kuhjasorteerimine loob tรคieliku binaarkuhja ja seejรคrel korduvalt extracts juur sorteeritud jรคrjestuse loomiseks.
  • ๐Ÿ”บ Heapify: Heapify toiming taastab heap omaduse swap abilping lapsevanem oma suurema lapsega.
  • ๐Ÿ—ƒ๏ธ Massiivi salvestusruum: Heap salvestatakse massiivi, kus i-ndal indeksil asuval sรตlmel on lapsed 2i+1 ja 2i+2 juures.
  • ๏ธ Keerukus: Kuhjasortimine tรถรถtab kรตigil juhtudel O(n log n) ajaga ja kasutab O(1) lisaruumi.
  • ๐Ÿ’ป Code Tingimusel: Tรถรถ Python ja C++ Programmid demonstreerivad heapify'i, heap building'i ja tรคielikku sorteerimist.

Mis on kuhjade sortimise algoritm?

Kuhjasortimine on รผks populaarsemaid ja kiiremaid sortimisalgoritme. See pรตhineb tรคielikul binaarpuu andmestruktuuril. Otsime maksimaalse elemendi ja asetame selle maksimaalse kuhja saamiseks tippu. Asetame selle binaarpuu รผlemsรตlme.

Oletame, et massiiv on antud, andmed = [10,5, 7, 9, 4, 11, 45, 17, 60].

Kui massiivi i-s (i=0,1,2,3 โ€ฆ) indeks on emasรตlm, on (2i+1) ja (2i+2) vasak ja parem alamsรตlm. Tรคieliku binaarpuu loomine selle massiiviga nรคeb vรคlja jรคrgmine:

Kuhjade sortimise algoritm

Teeme kuhjastamise protsessi massiivi algusest lรตpuni. Esialgu, kui teisendame massiivi puuks, nรคeb see vรคlja nagu รผlaltoodud. Nรคeme, et see ei sรคilita รผhtegi hunniku omadust (min-heap vรตi max hunnik). Sorteeritud massiivi saame kรตigi sรตlmede jaoks kuhjade moodustamise protsessiga.

Kuhjade sortimise rakendamine

Siin on mรตned kuhja sortimise algoritmi kasutusviisid:

  • Prioriteetsete jรคrjekordade loomine vajab hunniku sortimist. Kuna hepsort hoiab elemendi sorteerituna pรคrast iga sisestamist.
  • Kuhja andmestruktuur on tรตhus k leidmiselth antud massiivi suurim element.
  • Linuxi kernel kasutab vaikimisi hunniku sortimist sortimisalgoritm kuna sellel on O (1) ruumi keerukus.

Looge nรคite abil kuhjade sortimine

Siin koostame jรคrgmisest tรคielikust kahendpuust maksimaalse hunniku.

Looge nรคite abil kuhjade sortimine

Lehesรตlmed on 17, 60, 4, 11 ja 45. Neil pole alamsรตlme. Sellepรคrast on nad lehtede sรตlmed. Niisiis, alustame kuhjastamise meetodit nende emasรตlmest. Siin on sammud.

Step 1) Valige vasakpoolseim alampuu. Kui alamsรตlmed on suuremad, vahetage vanemsรตlm alamsรตlmega.

Siin on emasรตlm 9. Ja alamsรตlmed on 17 ja 60. Kuna 60 on suurim, vahetatakse 60 ja 9, et sรคilitada max kuhjaga.

Looge nรคite abil kuhjade sortimine

Step 2) Nรผรผd on kรตige vasakpoolsem alampuu kuhjatud. Jรคrgmine รผlemsรตlm on 7. Sellel vanemal on kaks alamsรตlme ja suurim on 45. Seega vahetatakse 45 ja 7.

Looge nรคite abil kuhjade sortimine

Looge nรคite abil kuhjade sortimine

Step 3) Sรตlmedel 60 ja 4 on emasรตlm 5. Kuna "5" on vรคiksem kui alamsรตlm 60, siis see vahetatakse.

Looge nรคite abil kuhjade sortimine

Looge nรคite abil kuhjade sortimine

Step 4) Nรผรผd on sรตlmel 5 alamsรตlm 17,9. See ei ole maksimaalse kuhja omaduse sรคilitamine. Niisiis, 5 asendatakse 17-ga.

Looge nรคite abil kuhjade sortimine

Step 5) Sรตlm 10 asendatakse 60-ga ja seejรคrel 17-ga. Protsess nรคeb vรคlja jรคrgmine.

Looge nรคite abil kuhjade sortimine

Looge nรคite abil kuhjade sortimine

Step 6) Kuni 5. sammuni lรตime maksimaalse hunniku. Iga vanemsรตlm on suurem kui tema alamsรตlmed. Juursรตlmel on maksimaalne vรครคrtus (60).

Mรคrge: Sorteeritud massiivi loomiseks peame asendama maksimaalse vรครคrtusega sรตlme selle jรคrglasega.

Seda protsessi nimetatakse "extract-maksโ€. Kuna 60 on maksimaalne sรตlm, fikseerime selle asukoha 0. indeksiga ja loome hunniku ilma sรตlmeta 60.

Looge nรคite abil kuhjade sortimine

Looge nรคite abil kuhjade sortimine

Step 7) Kui 60 on eemaldatud, on jรคrgmine maksimaalne vรครคrtus 45. Teeme protsessi โ€žNรคidetracโ€žt Maxโ€ uuesti sรตlmest 45.

Seekord saame 45 ja asendame juursรตlme selle jรคrglasega 17.

Peame esinema "Extract Maxโ€ kuni kรตik elemendid on sorteeritud.

Pรคrast nende sammude tegemist kuni me extracKรตikide maksimaalsete vรครคrtuste korral saame jรคrgmise massiivi.

Looge nรคite abil kuhjade sortimine

Mis on binaarne hunnik?

Binary Heap on omamoodi tรคielik binaarne puu andmete struktuur. Sellises puustruktuuris on pรตhisรตlm alamsรตlmedest suurem vรตi vรคiksem. Kui emasรตlm on vรคiksem, nimetatakse kuhja "Min Heap" ja kui vanem sรตlm on suurem, nimetatakse hunnikut "Max Heap".

Siin on nรคited minimaalsest ja maksimaalsest kuhjast.

Min Heap ja Max Heap
Min Heap ja Max Heap

Kui mรคrkate รผlaloleval joonisel "Min Heap", on emasรตlm alati vรคiksem kui selle alamsรตlmed. Puu otsast leiame vรคikseima vรครคrtuse 10.

Samamoodi on โ€žMax Heapโ€ puhul emasรตlm alati suurem kui alamsรตlmed. Maksimaalne element on "Max Heap" peasรตlmes.

Mis on "Heapify"?

โ€œHeapifyโ€ on kuhja pรตhimรตte, mis tagab sรตlme asukoha. Heapifys sรคilitab maksimaalne hunnik alati suhte vanema ja lapsega ning see tรคhendab, et vanemsรตlm on suurem kui alamsรตlmed.

Nรคiteks kui lisatakse uus sรตlm, peame kuhja รผmber kujundama. Siiski vรตib meil olla vaja sรตlmi muuta vรตi vahetada vรตi massiivi รผmber korraldada. See รผmberkujundamise protsessping Kuhja nimetatakse "kuhjamiseks".

Siin on nรคide kuhjamise toimimisest:

Uue sรตlme lisamine ja Heapify
Uue sรตlme lisamine ja kuhja lisamine

Siin on kuhjamise toimingud:

Step 1) Lisati sรตlm 65 kui sรตlme 60 parem alam.

Step 2) Kontrollige, kas รคsja lisatud sรตlm on suurem kui รผlem.

Step 3) Kuna see on รผlemsรตlmest suurem, vahetasime รตige alamsรตlme vanemaga.

Kuidas hunnikut ehitada

Enne hunniku ehitamist vรตi puu kuhjamist peame teadma, kuidas me seda ladustame. Kuna hunnik on tรคielik kahendpuu, on parem kasutada an massiivi kuhja andmete hoidmiseks.

Oletame, et massiiv sisaldab kokku n elementi. Kui "i" indeks on emasรตlm, on vasak sรตlm indeksis (2i+1), ja parem sรตlm on indeksis (2i+2). Eeldame, et massiivi indeks algab 0-st.

Kasutades seda, salvestame maksimaalse hunniku jรคrgmise massiivi sarnasesse kohta:

Max Heap massiivipรตhine esitus
Maksimaalse hunniku massiivipรตhine esitus

Kuhjade loomise algoritm sรคilitab kuhja omaduse. Kui vanemal ei ole รครคrmist vรครคrtust (vรคiksem vรตi suurem), vahetatakse see kรตige รครคrmuslikuma alamsรตlmega.

Siin on juhised maksimaalse hunniku kuhjamiseks.

Step 1) Alusta lehesรตlmest.

Step 2) Leia maksimum vanema ja laste vahel.

Step 3) Vahetage sรตlmed, kui alamsรตlme vรครคrtus on suurem kui vanemsรตlmel.

Step 4) Mine รผhe taseme vรตrra kรตrgemale.

Step 5) Jรคrgige samme 2,3,4, 0, XNUMX, kuni jรตuame indeksini XNUMX vรตi sorteerime kogu puu.

Siin on pseudokood rekursiivse hunniku jaoks (maksimaalne kuhja):

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)

Pseudo Code Heap Sort jaoks

Siin on hunniku sortimise algoritmi pseudokood:

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)

Nรคide kuhjasortimisest Code in 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);
}

Vรคljund:

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

Nรคide kuhjasortimisest Code in 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)

Vรคljund:

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

Kuhjade sortimise aja ja ruumi keerukuse analรผรผs

Aja keerukust ja ruumi keerukust saame analรผรผsida hunniku sortimiseks. Ajalise keerukuse huvides on meil jรคrgmised juhtumid:

  1. Parim juhtum
  2. Keskmine juhtum
  3. Halvimal juhul

Kuhja rakendatakse tรคielikul kahendpuul. Seega on binaarpuu alumisel tasemel maksimaalne sรตlmede arv. Kui alumisel tasemel on n sรตlme, siis รผlaloleval tasemel on n/2 sรตlme.

Aja ja ruumi keerukuse analรผรผs

Selles nรคites on 3. tasemel neli รผksust, 2. tasemel kaks ja 1. tasemel รผks รผksus. Kui objekte on kokku n, on kรตrgus vรตi kogutase Logi2(n). Seega vรตib รผhe elemendi sisestamine vรตtta maksimaalselt Log(n) iteratsiooni.

Kui tahame kuhjast vรตtta maksimaalse vรครคrtuse, vรตtame lihtsalt juursรตlme. Seejรคrel taaskรคivitage heapify. Iga hunnik vรตtab Logi2(n) aeg. NรคidetracMaksimumi leidmine vรตtab aega O(1).

Kuhjade sortimise algoritmi parim juhtumi aja keerukus

Kui kรตik elemendid on massiivi juba sorteeritud, kulub kuhja loomiseks O(n) aega. Sest kui loend on sorteeritud, vรตtab รผksuse sisestamine konstantse aja, mis on O(1).

Nii et parimal juhul kulub max- vรตi min-hunniku loomiseks O(n) aega.

Kuhjade sortimise algoritmi keskmine juhtumi aja keerukus

Elemendi vรตi elemendi sisestaminetracMaksimaalse juhtumi leidmine maksab O(log(n)) aega. Seega on kuhjasortimise algoritmi keskmine juhtumi aja keerukus O(n log(n)).

Kuhjade sortimise algoritmi halvimal juhul keerukus

Sarnaselt keskmisele juhtumile vรตime halvima stsenaariumi korral esineda n korda. Iga hunnik maksab O(log(n)) aega. Seega on ajaline keerukus halvimal juhul O(n log(n)).

Ruumi keerukus kuhjade sortimise algoritmi jaoks

Kuhja sortimine on kohapeal loodud algoritm. See tรคhendab, et รผlesande tรคitmiseks pole vaja lisamรคlu ega ajutist mรคlu. Kui nรคeme teostust, mรคrkame, et kasutasime sรตlmede vahetamiseks vahetust (). Muud loendit vรตi massiivi polnud vaja. Seega on ruumi keerukus O(1).

KKK

Kuhjasortimine ei ole stabiilne sortimisalgoritm, kuna see hรตlmab nii ehitamist kui ka katsetamist.tracKuhjast andmete sisestamine saab vรตrdsete elementide jรคrjekorda muuta. Kui vรตrdsete vรตtmete algse jรคrjekorra sรคilitamine on oluline, on parem valik stabiilne algoritm, nรคiteks รผhendamissortimine.

Kuhjasortimine garanteerib kรตigil juhtudel O(n log n) aja ja kasutab O(1) lisaruumi. Kiirsortimine on praktikas tavaliselt kiirem, kuid halbade pรถรถrdepunktide korral vรตib see halveneda O(nยฒ)-ni. Kuhjasortimine loobub kiirusest usaldusvรครคrse halvima stsenaariumi nimel.

Nii kuhjasortimine kui ka liitsortimine tรถรถtavad O(n log n) ajaga. Kuhjasortimine sorteerib kohapeal O(1) lisaruumiga, kuid on ebastabiilne. Liitsortimine on stabiilne, kuid vajab liitmiseks O(n) lisaruumi.

Tehisintellekti juhendajad saavad animeerida heapify protsessi, nรคidata, kuidas maksimaalne heap moodustub ja traciga ekstract-max samm. See visuaalne ja interaktiivne abi aitab algajatel paremini aru saada, kuidas kuhjasortimine massiivi jรคrjestab.

Jah. Tehisintellektiga kodeerimisassistendid saavad tรตlkida kuhjasortimise implementatsiooni keelte vahel, nรคiteks C++, Pythonja Java samal ajal kui keeping loogika puutumata. ร•ige vรคljundi kinnitamiseks peaksite teisendatud koodi ikkagi kompileerima ja testima.

Vรตta see postitus kokku jรคrgmiselt: