Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
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’’ = 32h-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
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.