89
Heap binari e HeapSort

Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Embed Size (px)

Citation preview

Page 1: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Heap binari e HeapSort

Page 2: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 3: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Pseudocodice di SelectSort

Page 4: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

ordinatidisordinati

j

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)

n1

j_max

Complessità O(n2) in ogni caso (anche in quello migliore)

Algoritmo di ordinamento stabile (perché?)

Page 5: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 6: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Alberi binari

sottoalbero sinistro

sottoalbero destro

nodo radice

Page 7: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 8: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Alberi

Radice

nodi interni nodi foglia

Grado 1

Grado 2

Grado 0

percorso dallaradice al nodo k

k

Profondità 3

Profondità 2

Profondità 1

Profondità 0

Altezza 3

Page 9: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 10: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Alberi binari quasi completi

nodi foglia

profondità h

profondità h-1

profondità 0

nodo di grado 1

Page 11: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Condizione sulla struttura dell’albero

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 sull’etichettatura dell’albero

Page 12: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di heap

45

34

2530

28

1222

2114 1615 20

La relazione d’ordine è fra padre e figli, non fra i due figli!

Page 13: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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 < !)

Page 14: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 15: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

20

Rappresentazione di uno heap come array

45

34

2530

28

1222

2114 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

1 2 3 4 5 6 7 8 9 10 11 12

45 34 28 30 25 22 12 14 21 15 16

Page 16: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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]

Page 17: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Rappresentazione di uno heap come array45

34

2530

28

1222

2114 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

45 34 28 30 25 22 12 14 21 15 16 201 2 3 4 5 6 7 8 9 10 11 12

Page 18: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 19: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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])

Page 20: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

Page 21: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

14

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

i_max = iIf l heapsize(A) and A[l] > A[i_max] then i_max = lIf r heapsize(A) and A[r] > A[i_max] then i_max = r

l r

A

34i_max

Page 22: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

14

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

If i_max i then “scambia A[i] e A[i_max]” ...

i_max l r

A34

14

Page 23: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

34

2514

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

If i_max i then “scambia A[i] e A[i_max]” Heapify(A,i_max)

l r

A

Page 24: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

34

2514

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

l r

A

i_max = iIf l heapsize(A) and A[l] > A[i_max] then i_max = lIf r heapsize(A) and A[r] > A[i_max] then i_max = r

i_max

30

Page 25: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

34

2514

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

l r

A

i_max

30

If i_max i then “scambia A[i] e A[i_max]” ...

30

14

Page 26: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

34

2530

28

1222

2114 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

i

If i_max i then “scambia A[i] e A[i_max]” Heapify(A,i_max)

A

Page 27: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di Heapify

45

34

2530

28

1222

2114 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

iA

I test sono falsil > heapsize(A)r > heapsize(A)per cui i_max = i(caso base)

i_max = iIf l heapsize(A) and A[l] > A[i_max] then i_max = lIf r heapsize(A) and A[r] > A[i_max] then i_max = r

Heapify termina!Ora vale la proprietà heap

Page 28: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

Complessità di Heapify

T(n) = max[O(1),O(1)+T(n’)]

O(1)

O(1)

f(n) = T(n’)

Page 29: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di Heapify

Ad ogni chiamata ricorsiva, Heapify viene eseguito su un sottoalbero di n’ nodi dell’albero di n nodi

n’ 2/3 n45

34

2530

28

1222

2114 1615

1

2 3

4 5 6 7

8 9 10 11

n’/n è massimo

n’ n’’

Sottoalbero completodi altezza h-1

Sottoalbero completodi altezza h-2

Page 30: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di Heapify

45

34

2530

28

1222

2114 15

1

2 3

4 5 6 7

8 9 10

n’ n’’

n’/n non è massimo(n’ è più piccolo!)

Page 31: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di Heapify

45

34

2530

28

1222

2114 1615

1

2 3

4 5 6 7

8 9 10 112012

n’ n’’

n’/n non è massimo(n è più grande!)

Page 32: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di Heapify

n’ = 2h - 1n’’ = 2h-1 - 1

n = 1 + n’ + n’’ = 32h-1 - 1

45

34

2530

28

1222

2114 1615

1

2 3

4 5 6 7

8 9 10 11

n’ n’’

Sottoalbero completodi altezza h-1

Sottoalbero completodi altezza h-2

n’/n = 2h-1/(3 2h-1 -1) 2/3

Page 33: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

Complessità di Heapify

Page 34: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

Page 35: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

1534

28

1220

2130 1625 22

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

i = 6

20

Page 36: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

1534

28

1220

2130 1625 22

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 22 12 30 21 25 16 201 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

2022

20

heap

i = 6

Page 37: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

1534

28

1222

2130 1625 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

15

i = 5

Page 38: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

1534

28

1222

2130 1625 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 25 20 12 30 21 15 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

15

i = 5

25

15

heap

i = 5

Page 39: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

34

heap

i = 4

Page 40: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

heap 28

i = 3

Page 41: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

45 heap

i = 2

Page 42: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

14 45 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

14

i = 1

Page 43: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

45

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

45 14 28 34 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

14

14

45

i = 1

Page 44: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

2534

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

45 34 28 14 15 20 12 30 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

1445

34

14

i = 1

Page 45: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

25

28

1222

2130 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

45 34 28 30 15 20 12 14 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

1445

34

30

14

i = 1

Page 46: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di applicazione di BuildHeap

14

25

28

1222

21 1615 20

1

2 3

4 5 6 7

8 9 10 11 12

45 34 28 30 15 20 12 14 21 25 16 221 2 3 4 5 6 7 8 9 10 11 12

BuildHeap(A)

For i = length(A)/2 downto 1 do

Heapify(A,i)

1445

34

30

14

heap

i = 1

Page 47: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)!

Page 48: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di BuildHeapBuildHeap 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

45

1534

28

1220

2130 1625 22

1

2 3

4 5 6 7

8 9 10 11 12

Page 49: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di BuildHeap

)(

2)(

log

11

hOn

nfn

hh

n

hh

hnO

log

1 22

0 22 hh

hnO

20 )1( x

xhx

h

h

Poiché )()2/11(

2/1

2)(

2nO

nOnf

Poiché TH = O(log n) e nh log

,

Page 50: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 51: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

HeapSort e SelectSort

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}

SelectSort(n,A)

For j = n downto 2 do

j_ max = FindMax(A,j)

“scambia A[j_max] e A[j]”

Page 52: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Intuizioni su HeapSort

n1disordinati

parzialmente ordinatiheap

n1

costruisci heapmax

scambio +

Heapifyn1

max

ordinatiparzialmente ordinatiheap

i

Page 53: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Un esempio di esecuzione di HeapSort

HeapSort(A)

BuildHeap(A)

14

45

1534

28

1220

2130 1625 22

2 3

4 5 6 7

8 9 10 11 12

34

2530 22

14 15 20

145

Page 54: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

45

1534

28

1220

2130 1625 22

1

2 3

4 5 6 7

8 9 12

34

2530

28

1222

2114 1615 20

45

45

20

j = 12

10 11

Page 55: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

45

1534

28

1220

2130 1625

2 3

4 5 6 7

8 9 10 11

34

2530

28

1222

2114 161512

1

45

45

20

j = 12

Page 56: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

45

1534

28

1220

2130 1625

2 3

4 5 6 7

8 9 10 11

34

2530

28

1222

2114 161512

1

45

45

20

j = 12

30

21

20

34

Page 57: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

15

28

1220

30 1625

2 3

4 5 6 7

8 9 10 11

25

28

1222

14 161512

1

45

45

20

j = 11

30

21

20

34

34

16

Page 58: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

15

28

1220

30 25

2 3

4 5 6 7

8 9 10 11

25

28

1222

14 1512

1

45

45

20

j = 11

30

21

20

34

34

16

Page 59: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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) 14

15

28

1220

30 25

2 3

4 5 6 7

8 9 10 11

25

28

1222

14 1512

1

45

45

20

j = 11

30

21

20

34

34

16

25

16

30

Page 60: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30 15

2 3

4 5 6 7

8 9 10 11

28

1222

1412

1

j = 10

21

20 34

25

16

30

30

15

45

Page 61: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

28

1222

1412

1

j = 10

21

20 34

25

16

30

30

15

45

Page 62: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

28

1222

1412

1

j = 10

21

20 34

25

16

30

30

15

45

22

15

28

Page 63: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

22

1215

1412

1

j = 9

21

20 34

25

16

30

30

28

45

20

28

Page 64: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

22

1215

1412

1

j = 9

21

34

25

16

30 45

20

28

Page 65: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

22

1215

1412

1

j = 9

21

34

25

16

30 45

20

28

20

21

25

Page 66: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

30

2 3

4 5 6 7

8 9 10 11

22

1215

1412

1

j = 8

34

16

30 4528

20

21

25

25

14

Page 67: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

2 3

4 5 6 7

8 9 10 11

22

1215

12

1

j = 8

34

16

30 4528

20

21

25

25

14

Page 68: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

28

1220

2 3

4 5 6 7

8 9 10 11

22

1215

12

1

j = 8

34

16

30 4528

20

21

25

25

14

15

14

22

Page 69: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

12

2 3

4 5 6 7

8 9 10 11

12

12

1

j = 7

34

16

30 4528

20

21

25

15

14

22

22

12

Page 70: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6

7 8 9 10 11 12

1

j = 7

34

16

30 4528

20

21

25

15

14

12

22

Page 71: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6

7 8 9 10 11 12

1

j = 7

34

16

30 4528

20

21

25

15

14

12

22

12

20

21

Page 72: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6

7 8 9 10 11 12

1

j = 6

34

16

30 4528

20

20

25

15

14

22

12

21

21

14

Page 73: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5

6 7 8 9 10 11 12

1

j = 6

34

16

30 4528

20

25

15

22

12

21

21

14

Page 74: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5

6 7 8 9 10 11 12

1

j = 6

34

16

30 4528

20

25

15

22

12

21

21

14

14

16

20

Page 75: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5

6 7 8 9 10 11 12

1

j = 5

3430 452825

15

22

12

21

14

16

20

20

14

Page 76: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4

5 6 7 8 9 10 11 12

1

j = 5

3430 452825

15

22

12

21

16

20

20

14

Page 77: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4

5 6 7 8 9 10 11 12

1

j = 5

3430 452825

15

22

12

21

16

20

20

14

14

16

Page 78: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4

5 6 7 8 9 10 11 12

1

j = 4

3430 452825

15

22

12

2120

14

16

16

12

Page 79: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6 7 8 9 10 11 12

1

j = 4

3430 452825

15

222120

14

16

16

12

Page 80: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6 7 8 9 10 11 12

1

j = 4

3430 452825

15

222120

14

16

16

12

12

15

Page 81: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3

4 5 6 7 8 9 10 11 12

1

j = 3

3430 452825222120

14

16

12

15

15

12

Page 82: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2

3 4 5 6 7 8 9 10 11 12

1

j = 3

3430 452825222120

14

16

15

15

12

Page 83: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2

3 4 5 6 7 8 9 10 11 12

1

j = 3

3430 452825222120

14

16

15

15

12

12

14

Page 84: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2

3 4 5 6 7 8 9 10 11 12

1

j = 2

3430 4528252221201615

12

14

14

12

Page 85: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3 4 5 6 7 8 9 10 11 12

1

j = 2

3430 4528252221201615

12

14

12

Page 86: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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)

2 3 4 5 6 7 8 9 10 11 121

j = 2

3430 45282522212016151412

L’array A ora è ordinato!

Page 87: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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

Page 88: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

Complessità di HeapSort

)(log nO

)(1O

HeapSort(A)

BuildHeap(A)

For j = n downto 2 do “scambia A[1] e A[j]”Heapify(A[1,…,j-1],1)

)(nO

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)

Page 89: Heap binari e HeapSort. Algoritmo SelectSort Invariante di ciclo : ad ogni passo gli ultimi i elementi del vettore corrente sono gli i elementi massimi

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