La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Heap binari e HeapSort.

Presentazioni simili


Presentazione sul tema: "Heap binari e HeapSort."— Transcript della presentazione:

1 Heap binari e HeapSort

2 Algoritmo SelectSort Invariante di ciclo: ad ogni passo
gli ultimi i elementi del vettore corrente sono gli i elementi massimi del vettore originale gli ultimi i elementi del vettore corrente sono ordinati Inizializzazione: i = 0 Passo: estrarre l’elemento massimo dal vettore [1..n-i] e scambiarlo con quello in posizione n-i Condizione di arresto: i = n

3 Pseudocodice di SelectSort
SelectSort(n,A) For j = n downto 2 do {estrai il massimo e mettilo in coda} j_ max = FindMax(A,j) “scambia A[j_max] e A[j]” FindMax(A,j) i_max = 1 For i = 2 to j do If A[i_max] < A[i] then i_max = i return i_max

4 SelectSort Scandisce la sequenza dall’ultimo elemento al primo
Ad ogni iterazione (FindMax) cerca l’elemento massimo A[j_max] nella sottosequenza corrente A[1,…,j] scambia l’ultimo elemento con quello massimo (facendo uscire l’elemento massimo dalla sequenza e ricompattandola) j_max j 1 n disordinati ordinati Algoritmo di ordinamento stabile (perché?) Complessità O(n2) in ogni caso (anche in quello migliore)

5 L’algoritmo di ordinamento HeapSort
E’ una variante di SelectSort in cui si estrae l’elemento massimo in tempo costante grazie a uno heap Lo heap è un albero binario quasi completo (struttura), in cui le etichette dei nodi rispettano certe condizioni Albero binario: insieme vuoto (albero vuoto o nullo) unione di tre sottoinsiemi disgiunti un nodo detto radice un albero binario detto sottoalbero sinistro un albero binario detto sottoalbero destro

6 Alberi binari nodo radice sottoalbero sinistro sottoalbero destro

7 Qualche definizione sugli alberi
Nodo foglia (o foglia) di un albero è un nodo i cui sottoalberi sono vuoti (non ha figli) Nodo interno di un albero è un nodo che ha figli Percorso dal nodo i al nodo j è la sequenza di archi da attraversare per raggiungere il nodo j dal nodo i Grado di un nodo è il numero dei suoi figli Profondità di un nodo è il numero di archi del percorso da esso alla radice Altezza di un albero è la profondità massima dei suoi nodi

8 Alberi percorso dalla radice al nodo k nodi interni nodi foglia Radice
Profondità 3 Profondità 2 Profondità 1 Profondità 0 Altezza 3 Radice Grado 1 Grado 2 Grado 0 nodi interni nodi foglia

9 Alberi binari completi (e quasi)
Albero binario: tutti i nodi hanno grado  2 Albero binario completo: tutti i nodi interni hanno grado 2 tutte le foglie hanno la stessa profondità Albero binario quasi completo tutte le foglie hanno profondità h o h-1 tutti i nodi interni hanno grado 2, eccetto al più uno se esiste un nodo di grado 1 è a profondità h-1 ha solo il figlio sinistro i nodi alla sua destra (se esistono) sono foglie

10 Alberi binari quasi completi
profondità 0 nodo di grado 1 profondità h-1 profondità h nodi foglia

11 Proprietà di uno heap Un albero heap è un albero binario quasi completo con etichette sui nodi, tali che per ogni nodo l’etichetta di entrambi i nodi figli non supera quella del padre. Condizione sulla struttura dell’albero Condizione sull’etichettatura dell’albero

12 Un esempio di heap La relazione d’ordine è fra padre e figli,
45 34 28 30 25 22 12 14 21 15 16 20 La relazione d’ordine è fra padre e figli, non fra i due figli!

13 Heap e ordinamenti parziali
Uno heap rappresenta un ordinamento parziale, cioè una relazione tra elementi di un insieme riflessiva: x è in relazione con se stesso x R x antisimmetrica: se x è in relazione con y e y è in relazione con x, allora x = y x R y  y R x  x = y transitiva: se x è in relazione con y e y è in relazione con z, allora x è in relazione con z x R y  y R z  x R z Esempi: le relazioni  e  (NON le relazioni > e < !)

14 Heap e ordinamenti parziali
Un albero binario di ricerca rappresenta un ordinamento totale: in un ordinamento totale per ogni coppia di elementi x e y vale o x R y o y R x Un ordinamento parziale è più debole di uno totale: possono esservi coppie di elementi privi di relazione Gli ordinamenti parziali modellano gerarchie con informazione incompleta o elementi con uguali valori Uno heap può essere implementato in vari modi; ad es., come un albero a puntatori, oppure come un array

15 Rappresentazione di uno heap come array
45 1 2 3 4 5 6 7 8 9 10 11 12 34 28 30 25 22 12 14 21 15 16 20 45 34 28 30 25 22 12 14 21 15 16 20

16 Rappresentazione di uno heap come array
la radice dello heap sta nella prima posizione dell’array se un nodo dello heap sta nella posizione i dell’array il figlio sinistro sta nella posizione 2i il figlio destro sta nella posizione 2i +1 viceversa, un array A rappresenta uno heap quando A[i ]  A[2i ] e A[i]  A[2i+1]

17 Rappresentazione di uno heap come array
45 1 34 28 2 3 30 25 22 12 4 5 6 7 14 21 15 16 20 8 9 10 11 12

18 Operazioni elementari su uno heap
LeftSubtree(i) {restituisce la radice del sottoalbero sinistro} return 2i RightSubtree(i) {restituisce la radice del sottoalbero destro} return 2i + 1 Father (i) {restituisce il nodo padre di i} return i/2 Indichiamo con heapsize(A)  n la dimensione dello heap Heapify(A,i): ripristina la proprietà di heap nel sottoalbero radicato in i, assumendo che valga già per i sottoalberi destro e sinistro di i BuildHeap(A): trasforma il generico array A in uno heap

19 Heapify Dati due heap H1 e H2 con radici k >1 e k+1
Si possono fondere i due heap in un albero H con radice in posizione i = k/2 Se l’ elemento v in posizione A[i] non è v  A[k] e v  A[k+1], allora H non è uno heap. Per renderlo tale: si scambia A[i] con la maggiore fra le radici di H1 e H2 si applica Heapify ricorsivamente al sottoalbero selezionato (con la nuova radice v in posizione A[2i] o A[2i+1])

20 Algoritmo Heapify Heapify(A,i) l = LeftRoot(i) r = RightRoot(i)
i_max = i If l  heapsize(A) and A[l] > A[i_max] then i_max = l If r  heapsize(A) and A[r] > A[i_max] then i_max = r If i_max  i then “scambia A[i] e A[i_max]” Heapify(A,i_max)

21 Un esempio di applicazione di Heapify
i_max = i If l  heapsize(A) and A[l] > A[i_max] then i_max = l If r  heapsize(A) and A[r] > A[i_max] then i_max = r 45 1 A i 14 28 2 3 34 i_max 34 l 25 r 22 12 4 5 6 7 30 21 15 16 20 8 9 10 11 12

22 Un esempio di applicazione di Heapify
If i_max  i then “scambia A[i] e A[i_max]” ... 45 1 A 34 14 i 14 28 2 3 i_max 34 l 25 r 22 12 4 5 6 7 30 21 15 16 20 8 9 10 11 12

23 Un esempio di applicazione di Heapify
If i_max  i then “scambia A[i] e A[i_max]” Heapify(A,i_max) 45 1 34 28 2 3 A i 14 25 22 12 4 5 6 7 l 30 r 21 15 16 20 8 9 10 11 12

24 Un esempio di applicazione di Heapify
i_max = i If l  heapsize(A) and A[l] > A[i_max] then i_max = l If r  heapsize(A) and A[r] > A[i_max] then i_max = r 45 1 34 28 2 3 A i 14 25 22 12 4 5 6 7 i_max 30 l 30 r 21 15 16 20 8 9 10 11 12

25 Un esempio di applicazione di Heapify
If i_max  i then “scambia A[i] e A[i_max]” ... 45 1 34 28 2 3 A 30 14 i 14 25 22 12 4 5 6 7 i_max l 30 30 r 21 15 16 20 8 9 10 11 12

26 Un esempio di applicazione di Heapify
If i_max  i then “scambia A[i] e A[i_max]” Heapify(A,i_max) 45 1 34 28 2 3 30 25 22 12 4 5 6 7 A i 14 21 15 16 20 8 9 10 11 12

27 Un esempio di applicazione di Heapify
i_max = i If l  heapsize(A) and A[l] > A[i_max] then i_max = l If r  heapsize(A) and A[r] > A[i_max] then i_max = r 45 I test sono falsi l > heapsize(A) r > heapsize(A) per cui i_max = i (caso base) 1 34 28 2 3 30 25 22 12 4 5 6 7 A i 14 21 15 16 Heapify termina! Ora vale la proprietà heap 20 8 9 10 11 12

28 Complessità di Heapify
T(n) = max[O(1),O(1)+T(n’)] Heapify(A,i) l = LeftRoot(i) r = RightRoot(i) i_max = i If l  heapsize(A) and A[l] > A[i_max] then i_max = l If r  heapsize(A) and A[r] > A[i_max] then i_max = r If i_max  i then “scambia A[i] e A[i_max]” Heapify(A,i_max) O(1) O(1) f(n) = T(n’)

29 Complessità di Heapify
Ad ogni chiamata ricorsiva, Heapify viene eseguito su un sottoalbero di n’ nodi dell’albero di n nodi n’  2/3 n Sottoalbero completo di altezza h-1 Sottoalbero completo di altezza h-2 45 1 n’’ n’ 34 28 2 3 30 25 22 12 4 5 6 7 n’/n è massimo 14 21 15 16 8 9 10 11

30 Complessità di Heapify
45 1 n’’ n’ 34 28 2 3 30 25 22 12 4 5 6 7 14 21 15 n’/n non è massimo (n’ è più piccolo!) 8 9 10

31 Complessità di Heapify
45 1 n’ n’’ 34 28 2 3 30 25 22 12 4 5 6 7 14 21 15 16 20 n’/n non è massimo (n è più grande!) 8 9 10 11 12

32 Complessità di Heapify
Sottoalbero completo di altezza h-1 Sottoalbero completo di altezza h-2 45 1 n’’ n’ 34 28 2 3 30 25 22 12 4 5 6 7 n’ = 2h - 1 n’’ = 2h-1 - 1 n = 1 + n’ + n’’ = 32h-1 - 1 14 21 15 16 8 9 10 11 n’/n = 2h-1/(3 2h-1 -1)  2/3

33 Complessità di Heapify
T(n) = max[O(1),max(O(1),O(1) + T(n’))]  max[O(1),max(O(1),O(1) + T(2n/ 3))]  T(2n/3) + (1) T(n) = O (log n) Sempre nel caso peggiore, T(n)  T(n/3) + (1) T(n) =  (log n) Heapify impiega tempo proporzionale all’altezza dell’albero T(n) = (log n)

34 BuildHeap Trasforma l’array A in uno heap riordinando i suoi elementi attraverso l’algoritmo Heapify Heapify richiede che i due sottoalberi di ogni elemento siano già heap, ma gli ultimi n/2 elementi dell’array lo sono già, perché sono foglie, cioè radici di sottoalberi vuoti Quindi, basta inserire nello heap i primi n/2 elementi, usando Heapify per ripristinare la proprietà heap sui sottoalberi radicati in essi BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i)

35 Un esempio di applicazione di BuildHeap
14 1 45 28 2 3 34 15 20 20 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 25 16 22 8 9 10 11 12

36 Un esempio di applicazione di BuildHeap
14 1 45 28 22 20 heap 2 3 34 15 20 20 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 25 16 22 8 9 10 11 12

37 Un esempio di applicazione di BuildHeap
14 1 45 28 2 3 34 15 15 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 25 16 20 8 9 10 11 12

38 Un esempio di applicazione di BuildHeap
14 i = 5 25 15 heap 1 45 28 2 3 34 15 15 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 25 16 20 8 9 10 11 12

39 Un esempio di applicazione di BuildHeap
14 1 45 heap 28 2 3 34 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

40 Un esempio di applicazione di BuildHeap
14 1 45 heap 28 28 2 3 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

41 Un esempio di applicazione di BuildHeap
14 1 45 45 heap 28 2 3 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

42 Un esempio di applicazione di BuildHeap
14 14 1 45 28 2 3 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

43 Un esempio di applicazione di BuildHeap
14 45 14 1 14 45 28 2 3 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

44 Un esempio di applicazione di BuildHeap
14 45 14 1 34 28 2 3 14 34 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 21 15 16 20 8 9 10 11 12

45 Un esempio di applicazione di BuildHeap
45 14 14 1 34 28 2 3 30 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 30 14 21 15 16 20 8 9 10 11 12

46 Un esempio di applicazione di BuildHeap
45 14 14 1 heap 34 28 2 3 30 25 22 12 4 5 6 7 BuildHeap(A) For i = length(A)/2 downto 1 do Heapify(A,i) 14 21 15 16 20 8 9 10 11 12

47 Complessità di BuildHeap
BuildHeap chiama n/2 volte Heapify E’ allora TBH(n) = n/2 TH(n) = O(n log n)? Sì, ma si può stringere la stima sino a TBH(n) = O(n) Costruire uno heap di n elementi costa solo O(n)!

48 Complessità di BuildHeap
BuildHeap chiama Heapify (n/2 volte su heap di altezza 0) (inutile eseguire) n/4 volte su heap di altezza 1 n/8 volte su heap di altezza 2 n/2h+1 volte su heap di altezza h 14 1 45 28 2 3 34 15 20 12 4 5 6 7 30 21 25 16 22 8 9 10 11 12

49 Complessità di BuildHeap
Poiché TH = O(log n) e Poiché ,

50 HeapSort HeapSort è una variante di SelectSort che mantiene la sequenza in uno heap, facilitando così cui la ricerca dell’elemento massimo si costruisce uno heap a partire dall’array non ordinato A si scandisce l’array a partire dall’ultimo elemento e ad ogni passo la radice A[1] (che è l’elemento massimo) viene scambiata con l’ultimo elemento dello heap corrente si riduce di uno la dimensione corrente dello heap si ripristina la proprietà heap con Heapify

51 HeapSort e SelectSort SelectSort(n,A) For j = n downto 2 do
j_ max = FindMax(A,j) “scambia A[j_max] e A[j]” HeapSort(A) BuildHeap(A) For j = n downto 2 do { heapsize(A) = j } “scambia A[1] e A[j]” { j_ max = 1 } Heapify(A[1,…,j-1],1) { ripristina lo heap, ridotto}

52 Intuizioni su HeapSort
1 disordinati costruisci heap max n 1 parzialmente ordinati heap max ordinati parzialmente ordinati heap i scambio + Heapify n 1

53 Un esempio di esecuzione di HeapSort
HeapSort(A) BuildHeap(A) 45 14 1 45 34 28 2 3 30 34 25 15 22 20 12 4 5 6 7 14 30 21 15 25 16 20 22 8 9 10 11 12

54 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 12 45 20 45 14 1 34 45 28 28 2 3 30 34 25 15 22 20 12 12 4 5 6 7 14 30 21 21 15 25 16 16 20 22 8 9 10 11 12

55 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 12 20 45 14 1 34 45 28 28 2 3 30 34 25 15 22 20 12 12 4 5 6 7 14 30 21 21 15 25 16 16 45 8 9 10 11 12

56 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 12 30 21 20 34 20 45 14 1 34 45 28 28 2 3 30 34 25 15 22 20 12 12 4 5 6 7 14 30 21 21 15 25 16 16 45 8 9 10 11 12

57 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 11 34 16 20 34 45 14 1 30 28 28 2 3 21 25 15 22 20 12 12 4 5 6 7 14 30 20 15 25 16 16 45 8 9 10 11 12

58 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 11 16 20 34 45 14 1 30 28 28 2 3 21 25 15 22 20 12 12 4 5 6 7 14 30 20 15 25 34 45 8 9 10 11 12

59 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 11 25 16 30 20 16 34 45 14 1 30 28 28 2 3 21 25 15 22 20 12 12 4 5 6 7 14 30 20 15 25 34 45 8 9 10 11 12

60 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 10 30 15 30 1 25 28 28 2 3 21 16 22 20 12 12 4 6 7 5 14 30 20 15 34 45 8 9 10 11 12

61 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 10 30 15 1 25 28 28 2 3 21 16 22 20 12 12 4 6 7 5 14 30 20 30 34 45 8 9 10 11 12

62 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 10 30 15 22 15 28 1 25 28 28 2 3 21 16 22 20 12 12 4 6 7 5 14 30 20 30 34 45 8 9 10 11 12

63 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 9 20 28 28 30 1 25 22 28 2 3 21 16 15 20 12 12 4 6 7 5 14 30 20 30 34 45 8 9 10 11 12

64 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 9 20 1 25 22 28 2 3 21 16 15 20 12 12 4 6 7 5 14 30 28 30 34 45 8 9 10 11 12

65 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 9 20 21 25 20 1 25 22 28 2 3 21 16 15 20 12 12 4 6 7 5 14 30 28 30 34 45 8 9 10 11 12

66 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 8 25 14 25 1 21 22 28 2 3 20 16 15 20 12 12 4 6 7 5 14 30 28 30 34 45 8 9 10 11 12

67 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 8 25 14 1 21 22 28 2 3 20 16 15 20 12 12 4 6 7 5 25 28 30 34 45 8 9 10 11 12

68 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 8 25 14 15 14 22 1 21 22 28 2 3 20 16 15 20 12 12 4 6 7 5 25 28 30 34 45 8 9 10 11 12

69 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 7 22 12 22 1 21 15 2 3 20 16 14 12 12 4 6 7 5 25 28 30 34 45 8 9 10 11 12

70 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 7 12 1 21 15 2 3 20 16 14 4 6 5 22 25 28 30 34 45 7 8 9 10 11 12

71 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 7 12 20 21 12 1 21 15 2 3 20 16 14 4 6 5 22 25 28 30 34 45 7 8 9 10 11 12

72 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 6 21 21 14 1 20 15 2 3 12 20 16 14 4 6 5 22 25 28 30 34 45 7 8 9 10 11 12

73 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 6 14 21 1 20 15 2 3 12 16 4 5 21 22 25 28 30 34 45 6 7 8 9 10 11 12

74 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 6 14 16 20 14 21 1 20 15 2 3 12 16 4 5 21 22 25 28 30 34 45 6 7 8 9 10 11 12

75 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 5 20 14 20 1 16 15 2 3 12 14 4 5 21 22 25 28 30 34 45 6 7 8 9 10 11 12

76 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 5 20 14 1 16 15 2 3 12 4 20 21 22 25 28 30 34 45 5 6 7 8 9 10 11 12

77 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 5 14 16 20 14 1 16 15 2 3 12 4 20 21 22 25 28 30 34 45 5 6 7 8 9 10 11 12

78 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 4 16 12 16 1 14 15 2 3 12 4 20 21 22 25 28 30 34 45 5 6 7 8 9 10 11 12

79 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 4 12 16 1 14 15 2 3 16 20 21 22 25 28 30 34 45 4 5 6 7 8 9 10 11 12

80 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 4 12 16 12 15 1 14 15 2 3 16 20 21 22 25 28 30 34 45 4 5 6 7 8 9 10 11 12

81 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 3 15 12 15 1 14 12 2 3 16 20 21 22 25 28 30 34 45 4 5 6 7 8 9 10 11 12

82 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 3 12 15 1 14 2 15 16 20 21 22 25 28 30 34 45 3 4 5 6 7 8 9 10 11 12

83 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 3 12 14 12 15 1 14 2 15 16 20 21 22 25 28 30 34 45 3 4 5 6 7 8 9 10 11 12

84 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 2 14 12 14 1 12 2 15 16 20 21 22 25 28 30 34 45 3 4 5 6 7 8 9 10 11 12

85 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 2 12 12 1 14 15 16 20 21 22 25 28 30 34 45 2 3 4 5 6 7 8 9 10 11 12

86 Un esempio di esecuzione di HeapSort
HeapSort(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) j = 2 L’array A ora è ordinato! 12 14 15 16 20 21 22 25 28 30 34 45 1 2 3 4 5 6 7 8 9 10 11 12

87 Invariante di ciclo per HeapSort
Invariante di ciclo: ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi del vettore originale gli ultimi i elementi del vettore corrente sono ordinati i primi n-i elementi del vettore corrente formano uno heap Inizializzazione: i = 0 e BuildHeap() Passo: estrarre l’elemento massimo dal vettore [1..n-i] e scambiarlo con quello in posizione n-i e recuperare la proprietà heap nel vettore [1..n-i-1] Condizione di arresto: i = n

88 Complessità di HeapSort
HeapSort(A) BuildHeap(A) For j = n downto 2 do “scambia A[1] e A[j]” Heapify(A[1,…,j-1],1) Nel caso peggiore HeapSort chiama 1 volta BuildHeap n-1 volte Heapify sullo heap corrente THS(n) = max[O(n), (n-1) max(O(1), TH(n))] = max[O(n), max(O(n), O(n log n))] = O(n log n)

89 Conclusioni su HeapSort
E’ un algoritmo di ordinamento sul posto per confronto e impiega tempo O(n log n) Non è un algoritmo elementare Sfrutta le proprietà della struttura dati astratta heap. Dimostra che una buona rappresentazione dei dati spesso facilita il progetto di buoni algoritmi


Scaricare ppt "Heap binari e HeapSort."

Presentazioni simili


Annunci Google