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.

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:
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.
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.
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.
Step 3) Sรตlmedel 60 ja 4 on emasรตlm 5. Kuna "5" on vรคiksem kui alamsรตlm 60, siis see vahetatakse.
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.
Step 5) Sรตlm 10 asendatakse 60-ga ja seejรคrel 17-ga. Protsess nรคeb vรคlja jรคrgmine.
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.
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.
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.

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:

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:

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:
- Parim juhtum
- Keskmine juhtum
- 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.
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).














