Sei sulla pagina 1di 32

Algoritmi e Strutture Dati

Lezione 10
L’heap
Oggi parleremo di …

Heap
definizione
rappresentazione
operazioni
 inserimento
 cancellazione
Code con priorità
Heap: definizione

Un albero massimo è un albero in cui il valore della


chiave di ogni nodo non è minore del valore della chiave
dei suoi figli
 un heap massimo è un albero binario completo che è anche un
albero massimo.

Un albero minimo è un albero in cui il valore della


chiave di ogni nodo non è maggiore del valore della
chiave dei suoi figli
 un heap minimo è un albero binario completo che è anche un
albero minimo.
Heap massimo: esempio

45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
8 9 10 11 12
Heap minimo: esempio

10
1

15 20
2 3

30 25 22 32
4 5 6 7

40 51 35 27
8 9 10 11
La struttura dati MaxHeap

Struttura MaxHeap
Dati: un albero binario completo di n > 0 elementi organizzati in modo che il valore in un nodo
qualsiasi sia maggiore o uguale a quelli contenuti nei figli.
Operazioni:
Create(max_size)  MaxHeap
crea un heap vuoto capace di contenere max_size elementi.
HeapFull(heap, n)  Booleano
if (n = max_size) then return TRUE else return FALSE.
HeapEmpty(heap, n)  Booleano
if (n > 0) then return FALSE else return TRUE.
Insert(heap, item, n)  MaxHeap
if (!HeapFull(heap, n)) then inserisci item in heap e restituisci l’heap risultante
else return errore.
Delete(heap, n)  elemento
if (!HeapEmpty(heap, n)) then return l’elemento massimo dell’heap ed eliminalo
dall’heap else return errore.
Heap: rappresentazione

Un heap può essere implementato


come un albero con puntatori
come un array

Un heap è un albero binario completo

Conviene utilizzare un array!


Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione

Un heap può essere implementato come un array


in cui
la radice dell’heap si trova nella posizione 1 dell’array
se il nodo i dello heap si trova nella posizione i
dell’array,
 il figlio sinistro di i si trova nella posizione 2i
 il figlio destro di i si trova nella posizione 2i +1
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: rappresentazione
45
1

34 28
2 3

30 25 22 12
4 5 6 7

14 21 15 16 20
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 20
Heap: proprietà

Un albero heap è un albero binario completo tale


che per ogni nodo i:
entrambi i nodi j e k figli di i sono NON maggiori di i.
Un array A è un heap se

A[i ]  A[2i ] e A[i ]  A[2i+1]

1 2 3 4 5 6 7 8 9 10 11 12
45 34 28 30 25 22 12 14 21 15 16 20
Heap: inserimento
20
1

18 17
2 3

16 13 12 11
4 5 6 7

15 12 10
8 9 10

1 2 3 4 5 6 7 8 9 10
20 18 17 16 13 12 11 15 12 10
Heap: inserimento
20
1

18 17
2 3

16 13 12 11
4 5 6 7

15 12 10 24
8 9 10 11

1 2 3 4 5 6 7 8 9 10 11
20 18 17 16 13 12 11 15 12 10 24
Heap: inserimento
20
1

18 17
2 3

16 24 12 11
4 5 6 7

15 12 10 13
8 9 10 11

1 2 3 4 5 6 7 8 9 10 11
20 18 17 16 24 12 11 15 12 10 13
Heap: inserimento
20
1

24 17
2 3

16 18 12 11
4 5 6 7

15 12 10 13
8 9 10 11

1 2 3 4 5 6 7 8 9 10 11
20 24 17 16 18 12 11 15 12 10 13
Heap: inserimento
24
1

20 17
2 3

16 18 12 11
4 5 6 7

15 12 10 13
8 9 10 11

1 2 3 4 5 6 7 8 9 10 11
24 20 17 16 18 12 11 15 12 10 13
Heap: inserimento

Si inserisce il nuovo elemento in fondo all’heap.

Per determinarne la corretta posizione nell’heap,


si percorre l’albero verso l’alto finché
si raggiunge la radice
una posizione i tale che il valore nella posizione del
padre i/2 sia almeno pari al valore da inserire.
Heap: inserimento

Un heap si rappresenta mediante un array heap


 di dimensione MAX_ELEMENTI se il numero
massimo di elementi è MAX_ELEMENTI-1
 inizialmente il numero di elementi n = 0
algoritmo insert_max_heap(elemento item)
// inserisce un nuovo item in un heap di n elementi

if (n = MAX_ELEMENTI-1) then
stampa "L'heap e' pieno"
return
nn+1
L’altezza dell’heap è
in log2 (n+1)
while (i ≠ 1 and item > heap[i/2]) do
heap[i]  heap[i/2]
i  i/2 O(log2 n)
heap[i]  item
Heap: cancellazione
24
24
1

20 17
2 3

16 18 12 11
4 5 6 7

15 12 10 13
8 9 10 11

1 2 3 4 5 6 7 8 9 10 11
24 20 17 16 18 12 11 15 12 10 13
Heap: cancellazione
13
1

20 17
2 3

16 18 12 11
4 5 6 7

15 12 10
8 9 10

1 2 3 4 5 6 7 8 9 10
13 20 17 16 18 12 11 15 12 10
Heap: cancellazione
20
1

13 17
2 3

16 18 12 11
4 5 6 7

15 12 10
8 9 10

1 2 3 4 5 6 7 8 9 10
20 13 17 16 18 12 11 15 12 10
Heap: cancellazione
20
1

18 17
2 3

16 13 12 11
4 5 6 7

15 12 10
8 9 10

1 2 3 4 5 6 7 8 9 10
20 18 17 16 13 12 11 15 12 10
Heap: cancellazione

Si “sostituisce” il algoritmo delete_max_heap  elemento


nodo radice con // cancella e restituisce l’elemento max in un heap di n elementi
l’ultimo nodo item  heap[1]
dell’heap. temp  heap[n]
n  n-1
padre  1
Per ripristinare figlio  2

l’heap, si percorre while (figlio ≤ n) do


l’albero verso il if (figlio < n and heap[figlio] < heap[figlio+1]) then
figlio  figlio+1
basso if (temp ≥ heap[figlio]) then break
heap[padre]  heap[figlio]
 si confronta il nodo padre  figlio
padre con i suoi figli figlio  2 × figlio
 si scambiano gli heap[padre]  temp
return item
O(log n) 2
elementi fuori posto.
Code con priorità

Le code di priorità rappresentano una delle applicazioni


più efficienti della struttura dati Heap.
Una coda con priorità è una struttura dati utilizzata per
mantenere un insieme di elementi a ciascuno dei quali è
associato un valore chiamato chiave.
Una coda di priorità supporta le seguenti operazioni
 inserimento: inserire un nuovo elemento nell’insieme
 maximum: restituire l’elemento dell’insieme con la chiave più
grande
 cancellazione: rimuovere e restituire l’elemento dell’insieme
con la chiave più grande.
Code con priorità: una applicazione

Una delle applicazioni più comuni è quella della


schedulazione dei lavori su computer condivisi
 per gestire le code di stampa.
La coda di priorità tiene traccia del lavoro da realizzare e
la relativa priorità.

Quando un lavoro viene eseguito o interrotto, il lavoro con


più alta priorità è selezionato da quelli in attesa utilizzando
la procedura di cancellazione.
Ad ogni istante un nuovo lavoro può essere aggiunto alla
coda.
Code con priorità: rappresentazioni

Una coda con priorità elimina l’elemento con la


priorità più elevata (o meno elevata).
Rappresentazione Inserimento Cancellazione

Array non ordinato O(1) O(n)

Lista concatenata non ordinata O(1) O(n)

Array ordinato O(n) O(1)

Lista concatenata ordinata O(n) O(1)

Heap massimo O(log2n) O(log2n)


Riassumendo …

Heap
definizione, rappresentazione, operazioni
Code con priorità

La prossima volta introdurremo la struttura dati


Albero Binario di Ricerca.

32