Algoritmo di ordinamento heap (con Code in Python and C++)
โก Riepilogo intelligente
L'algoritmo Heap Sort ordina un array costruendo un heap binario e ripetendolotracinserendo il suo valore radice nella sezione ordinata. Questa risorsa spiega heapify, heap max e min, pseudocodice e completo Python and C++ implementazioni con analisi della complessitร temporale.

Cos'รจ l'algoritmo di ordinamento heap?
L'algoritmo Heap Sort รจ uno degli algoritmi di ordinamento piรน popolari e veloci. Si basa sulla struttura dati ad albero binario completo. L'obiettivo รจ trovare l'elemento massimo e posizionarlo in cima all'heap, ovvero sul nodo padre dell'albero binario.
Diciamo che viene fornito un array, dati = [10,5, 7, 9, 4, 11, 45, 17, 60].
Nell'array, se l'indice i-esimo (i=0,1,2,3 โฆ) รจ un nodo genitore, allora (2i+1) e (2i+2) saranno i figli sinistro e destro. La creazione di un albero binario completo con questo array sarร simile a questa:
Eseguiremo il processo heapify dall'inizio alla fine dell'array. Inizialmente, se convertiamo l'array in un albero, apparirร come sopra. Possiamo vedere che non mantiene alcuna proprietร heap (min-heap o max heap). Otterremo l'array ordinato eseguendo il processo heapify per tutti i nodi.
Applicazione dell'ordinamento heap
Ecco alcuni utilizzi dell'algoritmo di ordinamento dell'heap:
- La costruzione di "code prioritarie" richiede l'ordinamento dell'heap. Perchรฉ heapsort mantiene l'elemento ordinato dopo ogni inserimento.
- La struttura dei dati heap รจ efficiente nel trovare kth elemento piรน grande in un dato array.
- Il kernel Linux utilizza l'ordinamento heap come impostazione predefinita algoritmo di ordinamento poichรฉ ha complessitร spaziale O(1).
Crea ordinamento heap con l'esempio
Qui costruiremo un heap massimo dal seguente albero binario completo.
I nodi foglia sono 17, 60, 4, 11 e 45. Non hanno alcun nodo figlio. Ecco perchรฉ sono nodi foglia. Quindi, avvieremo il metodo heapify dal loro nodo padre. Ecco i passaggi:
Passo 1) Seleziona il sottoalbero piรน a sinistra. Se i nodi figli sono maggiori, scambia il nodo genitore con il nodo figlio.
Qui il nodo genitore รจ 9. E i nodi figli sono 17 e 60. Poichรฉ 60 รจ il piรน grande, 60 e 9 verranno scambiati per mantenere il heap max.
Passo 2) Ora, il sottoalbero piรน a sinistra รจ heapificato. Il nodo genitore successivo รจ 7. Questo nodo genitore ha due nodi figli e il piรน grande รจ 45. Quindi, 45 e 7 verranno scambiati.
Passo 3) I nodi 60 e 4 hanno il nodo genitore 5. Poichรฉ โ5โ รจ piรน piccolo del nodo figlio 60, verrร scambiato.
Passo 4) Ora, il nodo 5 ha il nodo figlio 17,9. Ciรฒ non mantiene la proprietร heap massima. Quindi, 5 verrร sostituito con 17.
Passo 5) Il nodo 10 verrร scambiato con 60, quindi con 17. Il processo sarร simile al seguente.
Passo 6) Fino al passaggio 5 abbiamo creato l'heap massimo. Ogni nodo genitore รจ piรน grande dei suoi nodi figli. Il nodo radice ha il valore massimo (60).
Nota: Per creare l'array ordinato, dobbiamo sostituire il nodo con valore massimo con il suo successore.
Questo processo si chiama "extract maxโ. Poichรฉ 60 รจ il nodo massimo, fisseremo la sua posizione sull'indice 0 e creeremo l'heap senza il nodo 60.
Passo 7) Poichรฉ 60 viene rimosso, il valore massimo successivo รจ 45. Eseguiremo il processo โExtract Maxโ di nuovo dal nodo 45.
Questa volta otterremo 45 e sostituiremo il nodo radice con il suo successore 17.
Dobbiamo esibirciโExtract Max" finchรฉ tutti gli elementi non saranno ordinati.
Dopo aver eseguito questi passaggi fino a quando non saremotracImpostando tutti i valori massimi, otterremo il seguente array.
Cos'รจ l'heap binario?
Un heap binario รจ una sorta di completo albero binario struttura dati. In questo tipo di struttura ad albero, il nodo genitore รจ maggiore o minore dei nodi figli. Se il nodo genitore รจ piรน piccolo, l'heap รจ chiamato "Min Heap" e se il nodo genitore รจ piรน grande, l'heap รจ chiamato "Max Heap".
Ecco alcuni esempi di heap minimo e heap massimo.

Nella figura sopra, se noti il โโ"Min Heap", il nodo genitore รจ sempre piรน piccolo dei suoi nodi figli. In cima all'albero troviamo il valore piรน piccolo, 10.
Allo stesso modo, per il "Max Heap", il nodo genitore รจ sempre piรน grande dei nodi figli. L'elemento massimo รจ presente nel nodo head per il "Max Heap".
Che cosa รจ โHeapifyโ?
"Heapify" รจ il principio dell'heap che assicura la posizione del nodo. In Heapify, un heap massimo mantiene sempre una relazione con il padre e il figlio, e cioรจ il nodo padre sarร piรน grande dei nodi figlio.
Ad esempio, se viene aggiunto un nuovo nodo, dobbiamo rimodellare l'heap. Tuttavia, potremmo dover cambiare o scambiare i nodi o riorganizzare l'array. Questo processo di rimodellamentoping un heap viene chiamato โheapifyโ.
Ecco un esempio di come funziona heapify:

Ecco i passaggi per heapify:
Passo 1) Aggiunto il nodo 65 come figlio destro del nodo 60.
Passo 2) Controlla se il nodo appena aggiunto รจ maggiore del genitore.
Passo 3) Poichรฉ รจ piรน grande del nodo genitore, abbiamo scambiato il figlio destro con il suo genitore.
Come costruire l'heap
Prima di costruire l'heap o di heapificare un albero, dobbiamo sapere come lo memorizzeremo. Poichรฉ l'heap รจ un albero binario completo, รจ meglio usare un schieramento per contenere i dati dell'heap.
Diciamo che un array contiene un totale di n elementi. Se l'indice "i" รจ un nodo genitore, il nodo sinistro sarร all'indice (2i+1)e il nodo destro sarร in indice (2i+2). Supponiamo che l'indice dell'array inizi da 0.
Utilizzando questo, memorizziamo un heap massimo in un array simile al seguente:

L'algoritmo heapify mantiene la proprietร heap. Se il genitore non ha il valore estremo (piรน piccolo o piรน grande), verrร scambiato con il nodo figlio piรน estremo.
Ecco i passaggi per heapizzare un heap massimo:
Passo 1) Inizia dal nodo foglia.
Passo 2) Trova il massimo tra genitore e figli.
Passo 3) Scambia i nodi se il nodo figlio ha un valore maggiore del genitore.
Passo 4) Sali di un livello.
Passo 5) Segui i passaggi 2,3,4 fino a raggiungere l'indice 0 o ordinare l'intero albero.
Ecco lo pseudo-codice per heapify ricorsivo (heap massimo):
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)
Soprannome Code per l'ordinamento Heap
Ecco lo pseudo-codice per l'algoritmo di ordinamento dell'heap:
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)
Esempio di ordinamento Heap 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); }
Produzione:
Initial Array: 10 5 7 9 4 11 45 17 60 Sorted Array (descending order): 60 45 17 11 10 9 7 5 4
Esempio di ordinamento Heap 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)
Produzione:
Initial List: 10 5 7 9 4 11 45 17 60 After HeapSort: 60 45 17 11 10 9 7 5 4
Analisi della complessitร temporale e spaziale di Heap Sort
Ci sono complessitร temporale e complessitร spaziale che possiamo analizzare per l'ordinamento heap. Per la complessitร temporale abbiamo i seguenti casi:
- Caso migliore
- Caso medio
- Caso peggiore
L'heap รจ implementato su un albero binario completo. Quindi, al livello piรน basso dell'albero binario, ci sarร il numero massimo di nodi. Se il livello inferiore ha n nodi, il livello superiore avrร n/2 nodi.
In questo esempio, il livello 3 ha quattro elementi, il livello 2 ha due elementi e il livello 1 ha un elemento. Se รจ presente un numero totale di n elementi, l'altezza o il livello totale sarร Log2(N). Pertanto, l'inserimento di un singolo elemento potrebbe richiedere un massimo di iterazioni Log(n).
Quando vogliamo prendere il valore massimo dall'heap, prendiamo semplicemente il nodo radice. Poi, eseguiamo di nuovo heapify. Ogni heapify prende Log2(N) tempo. Es.tractrovare il massimo richiede un tempo O(1).
migliori Complessitร temporale del caso per l'algoritmo di ordinamento heap
Quando tutti gli elementi sono giร ordinati nell'array, ci vorrร O(n) tempo per costruire l'heap. Perchรฉ se l'elenco รจ ordinato, l'inserimento di un elemento richiederร il tempo costante O(1).
Quindi, nel migliore dei casi, ci vorrร O (n) tempo per creare un heap massimo o minimo.
Complessitร temporale media del caso per l'algoritmo di ordinamento heap
Inserimento di un elemento o extraccalcolare un massimo richiede un tempo O(log(n)). Quindi, la complessitร temporale media per l'algoritmo di ordinamento heap รจ O(nlog(n)).
Complessitร temporale del caso peggiore per l'algoritmo di ordinamento heap
Similmente al caso medio, nello scenario peggiore, potremmo eseguire heapify n volte. Ogni heapify costerร O(log(n)) di tempo. Quindi, la complessitร temporale del caso peggiore sarร O(nlog(n)).
Complessitร spaziale per l'algoritmo di ordinamento heap
Heap sort รจ un algoritmo progettato in loco. Ciรฒ significa che non รจ necessaria memoria extra o temporanea per eseguire l'attivitร . Se osserviamo l'implementazione, noteremo che abbiamo utilizzato swap() per eseguire lo scambio dei nodi. Non รจ stato necessario nessun altro elenco o array. Quindi, la complessitร dello spazio รจ O(1).














