Paolo Camurati
Dip. Automatica e Informatica
Politecnico di Torino
ADT Heap
Definizione: albero binario con
proprietà strutturale: quasi completo
(tutti i livelli completi, tranne
eventualmente l’ultimo, riempito da SX a
DX) quasi bilanciato
proprietà funzionale:
i r key(parent(i)) key(i)
conseguenza: chiave max nella radice
z 15 ba 10
d 12 m 11 g 5 e 4
x 9 y 8 pp 5 w 7 k 2 b 0
RIGHT(i) = 2i+2
il padre è h->A[PARENT(i)] dove
PARENT(i)=(i-1)/2
A.A. 2020/21 14 Code a priorità e heap 7
0 a20
Esempio 1 2 ba10
z15
3 d12 4 m11 5 g5 6 e4
maxN = 15 x9 y 8 pp 5 w 7 k2 b0
7 8 9 10 11 12
a z ba d m g e x y pp w k b
h->A
20 15 10 12 11 5 4 9 8 5 7 2 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
h->heapsize 13
void HEAPdisplay(Heap h) {
int i;
for (i = 0; i < h->heapsize; i++)
ITEMstore(h->A[i]);
}
3 14 4 7 5 9 6 3
3 4 4 7 5 9 6 3
LEFT(i) RIGHT(i)
2 8 1
7 8 9
3 8 4 7 5 9 6 3
i=8
2 4 1
7 8 9
1 1 2 3
3 2 4 16 5 9 6 10
14 8 7
HEAPify(h->A, 4)
7 8 9
HEAPify(h->A, 3) 1 1
2 3
3 2 4 16 5 9 6 10
14 8 7
7 8 9
1 1 2 3
3 14 4 16 5 9 6 10
2 8 7
7 8 9
1 1 2 10
3 14 4 16 5 9 6 3
2 8 7
7 8 9
0 4
1 16 2 10
3 14 4 7 5 9 6 3
2 8 1
7 8 9
1 14 2 10
3 8 4 7 5 9 6 3
2 4 1
7 8 9
Sostituendo in T(n):
𝑙𝑜𝑔 𝑛
T(n) = σ𝑖=02 2ilog2(n/2i)
𝑙𝑜𝑔2𝑛 i 𝑙𝑜𝑔2𝑛 i
= log2n 𝑖=0 2 − 𝑖=0 i2
σ σ
= log2n(2n-1) -2(1-(log2n+1)n+2nlog2n)
= 2n –log2n -2
= O(n)
Caratteristiche:
complessità: T(n)= O(n lg n).
in loco
non stabile
h->A 5 3 2 6 4 1 9 7
0 5
1 3 2 2
3 6 4 4 5 1 6 9
7 7
h->A 9 7 5 6 4 1 2 3
h->heapsize = 8
0 9
1 7 2 5
3 6 4 4 5 1 6 2
7 3
1 7 2 5
3 6 4 4 5 1 6 2
7 9
1 6 2 5
3 3 4 4 5 1 6 2
7 9
1 6 2 5
3 3 4 4 5 1 6 7
7 9
1 4 2 5
3 3 4 2 5 1 6 7
7 9
PQ PQinit(int maxN);
void PQfree(PQ pq);
int PQempty(PQ pq);
void PQinsert(PQ pq, Item val);
Item PQextractMax(PQ pq);
Item PQshowMax(PQ pq);
void PQdisplay(PQ pq);
int PQsize(PQ pq);
void PQchange(PQ pq, Item val);
discussione a parte
vettore/lista ordinato
non considerati qui,
cfr Tipi di Dato Astratto
heap di dati/indici.
chiave1 = priorità
A.A. 2020/21 14 Code a priorità e heap 37
Utente ADT I cat. coda a priorità di dati
PQinsert(pq, item) a q zz qa cd s w c
item pq->A
81 70 20 48 5 9 19 15
PQshowMax(pq)
item 0 1 2 3 4 5 6 7 8 9
PQextractMax(pq) pq->heapsize 8
item
0 a 81
1 q 70 2 zz 20
3 qa48 4 cd 5 5 s 9 6 w19
7 c 15
PQ PQinit(int maxN){
PQ pq = malloc(sizeof(*pq));
pq->A = (Item *)malloc(maxN*sizeof(Item));
pq->heapsize = 0;
return pq;
}
A.A. 2020/21 14 Code a priorità e heap 40
void PQfree(PQ pq){
free(pq->array);
free(pq);
}
0 a81
1 q70 2 zz20
3 qa48 4 cd 5 5 s9 6 w19
7 c15
0 1 2 3 4 5 6 7 8 9
pq->heapsize 9
0 a81
1 q70 2 zz20
3 qa48 4 cd 5 5 s9 6 w19
i=9
7 c15 8 creo foglia
A.A. 2020/21 14 Code a priorità e heap 45
pq->A a q zz qa cd s w c qa
81 70 20 48 5 9 19 15 48
0 1 2 3 4 5 6 7 8 9
pq->heapsize 9
0 a81
1 q70 2 zz20
3 qa48 4 cd 5 5 s9 6 w19
0 a81
1 q70 2 zz20
3 q 70 4 cd 5 5 s9 6 w19
7 c15 8 qa48
0 1 2 3 4 5 6 7 8 9
i >1 && 75 < 81 pq->heapsize 9
inserisco r 75
0 a81
1 r 75 2 zz20
3 q 70 4 cd 5 5 s9 6 w19
7 c15 8 qa48
0 1 2 3 4 5 6 7 8 9
pq->heapsize 9
0 a81
1 r 75 2 zz20
3 q70 4 cd 5 5 s9 6 w19
7 c15 8 qa48
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
0 qa48
1 r 75 2 zz20
3 q70 4 cd 5 5 s9 6 w19
pq->A[0] pq->A[pq->heapsize-1]
7 c15 8 a81 pq->heapsize--
A.A. 2020/21 14 Code a priorità e heap 52
pq->A r q zz qa cd s w c a
75 70 20 48 5 9 19 15 81
HEAPify(pq->A, 0)
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
0 r 75
1 q70 2 zz20
3 qa48 4 cd 5 5 s9 6 w19
7 c15 8 a81
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
0 a81
Cambio la priorità di w da 19
a 90. L’elemento si trova
1 q70 2 zz20 all’indice 6.
3 qa48 4 cd 5 5 s9 6 w19
7 c15
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
0 a81
20 < 90,
1 q70 zz 20 scende
2 zz20
3 qa48 4 cd 5 5 s9 6 zz20
7 c15
0 a81
1 q70 2 a 81
3 qa48 4 cd 5 5 s9 6 zz20
7 c15
0 w90
1 q70 2 a 81
3 qa48 4 cd 5 5 s9 6 zz20
7 c15
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
0 w90
Cambio la priorità di q da 70
a 3. L’elemento si trova
1 q70 2 a 81 all’indice 1.
3 qa48 4 cd 5 5 s9 6 zz20
7 c15
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
cambio 70 in 3 0 w90
1 q3 2 a 81
3 qa48 4 cd 5 5 s9 6 zz20
7 c15
0 1 2 3 4 5 6 7 8 9
pq->heapsize 8
1 qa48 2 a 81
3 c15 4 cd 5 5 s9 6 zz20
7 q3
if (found==1) {
while(pos>=1 &&
PRIOget(pq->array[PARENT(pos)])<PRIOget(val)){
pq->array[pos] = pq->array[PARENT(pos)];
pos = (pos-1)/2;
}
pq->array[pos] = val;
Heapify(pq, pos);
}
else
printf("key not found!\n");
return;
}
A.A. 2020/21 14 Code a priorità e heap 62
Cosa contiene l’ADT Coda a priorità?
typedef struct {
char name[MAXC];
int prio;
} Item; funzioni su elementi
di tipo Item
typedef char *Name;
Item ITEMscan();
void ITEMstore(Item val); funzioni su:
Item ITEMsetNull();
• nome
Name NAMEget(Item *pval); • priorità
int NAMEcmp(Name n1, Name n2);
int PRIOget(Item val);
ST STinit(int maxN);
void STfree(ST st);
int STinsert(ST st, Item val, int index);
int STsearch(ST st, Item val, int *index);
void STchangePrio(ST st, Item val, int i);
cerca e ritorna
un elemento e il
cambia la priorità di un
suo indice in
elemento in posizione i
st->a
A.A. 2020/21 14 Code a priorità e heap 69
tabella di hash con open addressing, linear
probing e cancellazione logica
ST.c
...
struct symboltable { Item *a; int *ind; int M;};
S STACKinit(int maxN);
void STACKfree(S s);
void STACKpush(S s, int index);
int STACKpop(S s);
Stack.c
...
typedef struct STACKnode* link;
struct STACKnode { int index; link next; };
S STACKinit(int maxN) {
S s = malloc(sizeof *s);
s->top = NULL; s->N = 0;
return s;
}
A.A. 2020/21 14 Code a priorità e heap 74
void STACKfree(S s) {
link t, u;
for (t = s->top; t != NULL; t = u){
u = t->next; free(t);
}
free(s->top);
free(s);
}
void STACKpush(S s, int ind) {
s->top = NEW(ind, s->top); (s->N)++;
}
int STACKpop(S s) {
int ind = s->top->index;
link t = s->top->next;
free(s->top); s->top = t; (s->N)--;
return ind;
}
A.A. 2020/21 14 Code a priorità e heap 75
PQ.h
typedef struct pqueue *PQ;
PQ PQinit(int maxN);
void PQfree(PQ pq);
int PQempty(PQ pq);
int PQsize(PQ pq);
void PQinsert(PQ pq, Item val);
Item PQshowMax(PQ pq);
Item PQextractMax(PQ pq);
void PQdisplay(PQ pq);
void PQchange(PQ pq, Item val);
PQ PQinit(int maxN) {
int i; float alpha=0.5;
PQ pq = malloc(sizeof(*pq));
pq->heap = malloc(maxN*sizeof(int));
pq->vett = malloc(maxN*sizeof(Item));
pq->vettsize = 0;
pq->hash = STinit(maxN, alpha);
pq->qp = malloc(maxN*sizeof(int));
for (i=0; i < maxN; i++){
pq->heap[i] = -1; pq->qp[i] = -1;
pq->vett[i] = ITEMsetNull();
}
pq->heapsize = 0;
pq->stack = STACKinit(maxN);
return pq;
}
A.A. 2020/21 14 Code a priorità e heap 77
void PQfree(PQ pq) {
STACKfree(pq->stack);
free(pq->qp);
STfree(pq->hash);
free(pq->vett);
free(pq->heap);
free(pq);
}
pq->heap pq->heapsize 0
0 1 2 3 4
pq->qp pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 82
0 0
inserzione di ZZ, 20
pq
ZZ creo nuova foglia e
pq->vett 20 aggiorno heapsize
0 1 2 3 4
ZZ
pq->hash
20
0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap pq->heapsize 1
0 1 2 3 4
pq->qp pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 83
ZZ
0 0 0 20
inserzione di ZZ, 20
pq
ZZ sono nella radice:
pq->vett 20 pq->heap[0]=0
0 1 2 3 4 pq->qp[0]=0
ZZ
pq->hash
20
0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 pq->heapsize 1
0 1 2 3 4
pq->qp 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 84
ZZ
0 0 0 20
inserzione di A, 81
pq
ZZ A inserisco in pq->vett
pq->vett 20 81 e pq->hash
0 1 2 3 4
A ZZ
pq->hash
81 20
1 0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 pq->heapsize 1
0 1 2 3 4
pq->qp 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 85
ZZ
0 0 0 20
inserzione di A, 81 1 1
pq
ZZ A creo nuova foglia e
pq->vett 20 81 aggiorno heapsize
0 1 2 3 4
A ZZ
pq->hash
81 20
1 0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 pq->heapsize 2
0 1 2 3 4
pq->qp 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 86
ZZ
0 0 0 20
ZZ
inserzione di A, 81 1 0 1 20
pq
ZZ A i >=1 && 81>20, ZZ (0)
pq->vett 20 81 scende, pq->heap[1]=0
0 1 2 3 4 e pq->qp[0]=1
A ZZ
pq->hash
81 20
1 0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 0 pq->heapsize 2
0 1 2 3 4
pq->qp 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 87
A
0 1 0 81
ZZ
inserzione di A, 81 1 0 1 20
pq
ZZ A sono nella radice:
pq->vett 20 81 pq->heap[0]=1
0 1 2 3 4 pq->qp[1]=0
A ZZ
pq->hash
81 20
1 0
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 pq->heapsize 2
0 1 2 3 4
pq->qp 1 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 88
A
0 1 0 81
ZZ
inserzione di DA, 15 1 0 1 20
pq
ZZ A DA inserisco in pq->vett
pq->vett 20 81 15 e pq->hash
0 1 2 3 4
A ZZ DA
pq->hash 15
81 20
1 0 2
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 pq->heapsize 2
0 1 2 3 4
pq->qp 1 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 89
A
0 1 0 81
ZZ
inserzione di DA, 15 1 0 2 1 20 2
pq
ZZ A DA creo nuova foglia e
pq->vett 20 81 15 aggiorno heapsize
0 1 2 3 4
A ZZ DA
pq->hash 15
81 20
1 0 2
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 pq->heapsize 3
0 1 2 3 4
pq->qp 1 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 90
A
0 1 0 81
ZZ
inserzione di DA, 15 1 0 2 2 1 20 2
DA
15
pq
ZZ A DA i >=1 && 15<81:
pq->vett 20 81 15 pq->heap[2]=2
0 1 2 3 4 pq->qp[2]=2
A ZZ DA
pq->hash 15
81 20
1 0 2
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 pq->heapsize 3
0 1 2 3 4
pq->qp 1 0 2 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 91
A
0 1 0 81
ZZ
inserzione di CD, 5 0 2 2 1 20 2
DA
15
pq
ZZ A DA CD inserisco in pq->vett
pq->vett 20 81 15 5 e pq->hash
0 1 2 3 4
A ZZ DA CD
pq->hash 15
81 20 5
1 0 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 pq->heapsize 3
0 1 2 3 4
pq->qp 1 0 2 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 92
A
0 1 0 81
ZZ
inserzione di CD, 5 1 0 2 2 1 20 2
DA
15
3 3 pq
ZZ A DA CD creo nuova foglia e
pq->vett 20 81 15 5 aggiorno heapsize
0 1 2 3 4
A ZZ DA CD
pq->hash 15
81 20 5
1 0 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 pq->heapsize 4
0 1 2 3 4
pq->qp 1 0 2 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 93
A
0 1 0 81
ZZ
inserzione di CD, 5 1 0 2 2 1 20 2
DA
15
CD
3 3 3 5 pq
ZZ A DA CD i >=1 && 5<20:
pq->vett 20 81 15 5 pq->heap[3]=3
0 1 2 3 4 pq->qp[3]=3
A ZZ DA CD
pq->hash 15
81 20 5
1 0 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 3 pq->heapsize 4
0 1 2 3 4
pq->qp 1 0 2 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 94
A
0 1 0 81
ZZ
inserzione di Q, 70 1 0 2 2 1 20 2
DA
15
CD
3 3 3 5 pq
ZZ A DA CD Q inserisco in pq->vett
pq->vett 20 81 15 5 70 e pq->hash
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 3 pq->heapsize 4
0 1 2 3 4
pq->qp 1 0 2 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 95
A
0 1 0 81
ZZ
inserzione di Q, 70 1 0 2 2 1 20 2
DA
15
CD
3 3 4 3 5 4 pq
ZZ A DA CD Q creo nuova foglia e
pq->vett 20 81 15 5 70 aggiorno heapsize
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 3 pq->heapsize 5
0 1 2 3 4
pq->qp 1 0 2 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 96
A
0 1 0 81
ZZ
inserzione di Q, 70 1 0 2 2 1 20 2
DA
15
CD ZZ
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q i >=1 && 70>20, ZZ (0)
pq->vett 20 81 15 5 70 scende, pq->heap[4]=0
0 1 2 3 4 e pq->qp[0]=4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 0 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 97
A
0 1 0 81
Q
inserzione di Q, 70 1 4 2 2 1 70 2
DA
15
CD ZZ
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q i >=1 && 70<81:
pq->vett 20 81 15 5 70 pq->heap[1]=4
0 1 2 3 4 pq->qp[4]=1
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 98
Funzione PQextractMax
Modifica pq->heap, estraendone il valore
massimo, che è contenuto nella radice:
scambia la radice con l'ultima delle foglie
(quella più a destra nell'ultimo livello)
riduce di 1 della dimensione dello heap
ripristina le proprietà dello heap mediante
applicazione di HEAPify
l’accesso al dato avviene attraverso pq->vett
HEAPify e Swap aggiornano anche pq->qp.
A.A. 2020/21 14 Code a priorità e heap 99
Modifica pq->vett e pq->hash:
inserisce l’indice dell’elemento estratto in
pq->stack per futuro eventuale riuso
cancella logicamente l’elemento estratto da
pq->hash
Esempio 1 4 2 2 1
CD
70
ZZ
2 15
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q
pq->vett 20 81 15 5 70
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 104
ZZ
0 0 0 20
Q DA
1 4 2 2 1 70 2 15
CD A
3 3 4 1 3 5 4 81 pq
ZZ A DA CD Q scambio pq->heap[0] e
pq->vett 20 81 15 5 70 pq->heap[pq->heapsize-1]
0 1 2 3 4 push dell’indice 1 su pq->stack
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 4 2 3 1 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack 1
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 105
ZZ
0 0 0 20
Q DA
1 4 2 2 1 70 2 15
CD
3 3 3 5 pq
ZZ A DA CD Q decremento heapsize
pq->vett 20 81 15 5 70 cancello da pq->hash
0 1 2 3 4 aggiorno pq->qp
A ZZ Q DA CD
pq->hash
81 20 70 15 5
-2 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 0 4 2 3 pq->heapsize 4
0 1 2 3 4
pq->qp 0 -1 2 3 1 pq->stack 1
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 106
Q
0 4 0 70
ZZ DA
1 0 2 2 1 20 2 15
CD
3 3 3 5 pq
ZZ A DA CD Q applico Heapify(pq->heap[0]),
pq->vett 20 81 15 5 70 aggiorno pq->qp
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
-2 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 4 0 2 3 pq->heapsize 4
0 1 2 3 4
pq->qp 1 -1 2 3 0 pq->stack 1
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 107
Q
0 4 0 70
ZZ
inserzione di XX, 1 DA
1 0 2 2 1 20 2 15
CD
3 3 3 5 pq
ZZ A DA CD Q pop 1 da pq->stack, inserisco
pq->vett 20 81 15 5 70 XX, 1 in pq->vett[1]
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
-2 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 4 0 2 3 pq->heapsize 4
0 1 2 3 4
pq->qp 1 -1 2 3 0 pq->stack 1
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 108
Q
0 4 0 70
ZZ DA
1 1 2 2 1 20 2 15
CD
3 3 4 3 5 4 pq
ZZ XX DA CD Q inserisco XX, 1 in pq->hash
pq->vett 20 1 15 5 70 creo foglia, aggiorno heapsize
0 1 2 3 4
A ZZ Q DA XX CD
pq->hash
81 20 70 15 1 5
-2 0 4 2 6 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 4 0 2 3 pq->heapsize 5
0 1 2 3 4
pq->qp 1 -1 2 3 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 109
Q
0 4 0 70
ZZ DA
1 0 2 2 1 20 2 15
CD XX
3 3 4
1 3 5 4 1 pq
ZZ XX DA CD Q i >=1 && 1<20:
pq->vett 20 1 15 5 70 pq->heap[4]=1
0 1 2 3 4 pq->qp[1]=4
A ZZ Q DA XX CD
pq->hash
81 20 70 15 1 5
-2 0 4 2 6 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 4 0 2 3 1 pq->heapsize 5
0 1 2 3 4
pq->qp 1 4 2 3 0 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 110
Funzione PQchange
La tabella di hash pq->hash ritorna con costo
unitario l’indice dell’elemento
Il vettore pq->qp, dato l’indice dell’elemento,
ritorna con costo unitario la posizione
dell’elemento nello heap
Si risale dalla posizione data fino al più alla radice
confrontando la chiave del padre con la chiave
modificata, facendo scendere la chiave del padre
nel figlio se la chiave modificata è maggiore,
altrimenti la inserisce nel nodo corrente
Si applica HEAPify a partire dalla posizione data.
A.A. 2020/21 14 Code a priorità e heap 111
indice dell’elemento indice dell’elemento
in pq->vett in pq->hash
void PQchange (PQ pq, Item item) {
int i, pos, temp, j;
i = STsearch(pq->hash, item, &j);
if (i == -1) {
printf("Item not found!\n");
return;
}
if (i == -2) {
printf("Item deleted!\n");
return;
}
STchangePrio(pq->hash, item, j);
pos = pq->qp[i];
temp = pq->heap[pos];
pq->vett[i] = item;
posizionamento corretto in risalita
CD da 5 a 90 1 4 2 2 1
CD
70
ZZ
2 15
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q
pq->vett 20 81 15 5 70
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 114
A
0 1 0 81
Q DA
1 4 2 2 1 70 2 15
CD ZZ
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q da pq->hash ricavo:
pq->vett 20 81 15 5 70 indice di CD in pq->vett: 3
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 115
A
1 0 81
Q DA
1 4 2 2 1 70 2 15
CD ZZ
3 3 4 0 3 5 4 20 pq
ZZ A DA CD Q da pq->qp ricavo:
pq->vett 20 81 15 5 70 indice di CD (3) in pq->heap: 3
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 5
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 116
A
1 0 81
Q DA
1 4 2 2 1 70 2 15
CD ZZ
3 3 4 0 3 90 4 20 pq
ZZ A DA CD Q aggiorno priorità in pq->vett
pq->vett 20 81 15 90 70 e pq->hash
0 1 2 3 4
A ZZ Q DA CD
pq->hash
81 20 70 15 90
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 3 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 1 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 117
A
1 0 81
Q DA
1 4 2 2 1 70 2 15
Q ZZ
3 4 4 0 3 70 4 20 pq
ZZ A DA CD Q i >=1 && 90>70, Q (4)
pq->vett 20 81 15 90 70 scende, pq->heap[3]=4
0 1 2 3 4 e pq->qp[4]=3
A ZZ Q DA CD
pq->hash
81 20 70 15 90
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 4 2 4 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 0 2 3 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 118
A
1 0 81
A DA
1 1 2 2 1 81 2 15
Q ZZ
3 4 4 0 3 70 4 20 pq
ZZ A DA CD Q i >=1 && 90>81, A (1)
pq->vett 20 81 15 90 70 scende, pq->heap[1]=1
0 1 2 3 4 e pq->qp[1]=1
A ZZ Q DA CD
pq->hash
81 20 70 15 90
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 1 1 2 4 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 1 2 3 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 119
CD
3 0 90
A DA
1 1 2 2 1 81 2 15
Q ZZ
3 4 4 0 3 70 4 20 pq
ZZ A DA CD Q sono nella radice
pq->vett 20 81 15 90 70 pq->heap[0]=3
0 1 2 3 4 e pq->qp[3]=0
A ZZ Q DA CD
pq->hash
81 20 70 15 90
1 0 4 2 3
0 1 2 3 4 5 6 7 8 9 10 11 12
pq->heap 3 1 2 4 0 pq->heapsize 5
0 1 2 3 4
pq->qp 4 1 2 0 3 pq->stack
0 1 2 3 4
A.A. 2020/21 14 Code a priorità e heap 120
Riferimenti
Heap:
Cormen 7.2, 7.3
Sedgewick 9.2, 9.3
Heapsort:
Cormen 7.4
Sedgewick 9.4
Code a priorità:
Cormen 7.5
Sedgewick 9.1, 9.6