Esempio:
M = 19
k = 31
h(k) = 31 % 19 = 12
A.A. 2020/21 13 Le tabelle di hash 10
M numero primo evita:
di usare solo gli ultimi n bit di k se M = 2n
di usare solo le ultime n cifre decimali di k
se M = 10n.
A = f = (5 – 1) / 2 = 0.6180339887
h(k) = kA % M
linear chaining
open addressing.
A.A. 2020/21 13 Le tabelle di hash 21
Linear Chaining
X
0 A
1 G
2 M H C R
3 X N I S
4 E
M
st = malloc(sizeof(*st));
st->N = 0;
st->M = STsizeSet(maxN, r);
st->heads = malloc(st->M*sizeof(link));
st->z = NEW(ITEMsetNull(), NULL);
return st;
}
Linear probing
Quadratic probing
Double hashing
A S E R C H I N G X M P
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2 NB: non si
0 A 0 A 0 A 0 A rispetta
1 1 1 1
2 2 2 2
il vincolo
3 3 3 3 <½
4 4 4 E 4 E
5 5 S 5 S 5 S cluster
A 6 S 6 E 6 R 6 R
7 7 7 7
8 8 8 8
9 9 9 9
10 10 10 10
11 11 11 11
12 12 12 12
A.A. 2020/21 13 Le tabelle di hash 42
A S E R C H I N G X M P
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2
0 A
1 i = h(’R’) = 82 % 13 = 4 collisione
2 i = (4+1) % 13 = 5 collisione
3 i = (5+1) % 13 = 6
4 E
5 S cluster
R 6 R
7
8
9
10
11
12
A.A. 2020/21 13 Le tabelle di hash 43
A S E R C H I N G X M P
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2
0 A 0 A 0 A 0 A
1 1 1 1 N
2 C 2 C 2 C 2 C
3 3 3 3
4 E 4 E 4 E 4 E
5 S 5 S 5 S 5 S
C 6 R H 6 R I 6 R N 6 R
7 7 H 7 H 7 H
8 8 8 I 8 I
9 9 9 9
10 10 10 10
11 11 11 11
12 12 12 12
A.A. 2020/21 13 Le tabelle di hash 44
A S E R C H I N G X M P
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2
0 A
1 N i = h(’N’) = 78 % 13 = 0 collisione
2 C i = (0+1) % 13 = 1
3
4 E
5 S
N 6 R
7 H
8 I
9
10
11
12
A.A. 2020/21 13 Le tabelle di hash 45
A S E R C H I N G X M P
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2
0 A
1 N i = h(’G’) = 71 % 13 = 6 collisione
2 C i = (6+1) % 13 = 7 collisione
3
4 E i = (7+1) % 13 = 8 collisione
5 S i = (8+1) % 13 = 9
G 6 R
7 H
8 I
9 G
10
11
12
A.A. 2020/21 13 Le tabelle di hash 46
A S E R C H I N G X M P collisione
h(k) = 0 5 4 4 2 7 8 0 6 10 12 2
0 A 0 A 0 A
i = h(’P’) = 80 % 13 = 2
1 N 1 N 1 N
2 C 2 C 2 C i = (2+1) % 13 = 3
3 3 3 P
4 E 4 E 4 E
5 S 5 S 5 S
6 R M 6 R P 6 R
7 H 7 H 7 H
8 I 8 I 8 I
9 G 9 G 9 G
10 X 10 X 10 X
11 11 11
12 12 M 12 M
A.A. 2020/21 13 Le tabelle di hash 47
Delete:
operazione complessa che interrompe le
catene di collisione.
L’open addressing è in pratica utilizzato solo
quando non si deve mai cancellare.
Soluzioni:
1. sostituire la chiave cancellata con una chiave
sentinella che conta come piena in ricerca e vuota
in inserzione
2. reinserire le chiavi del cluster sottostante la chiave
cancellata
A.A. 2020/21 13 Le tabelle di hash 48
Soluzione 1
Nell’ADT si introduce un vettore status di
interi: 0 se la cella è vuota, 1 se è occupata, -1
se cancellata.
La funzione CheckFull controlla se la cella i è
piena (status=1). La funzione
CheckDeleted controlla se la cella è piena
(status=1).
struct symboltable { Item *a; int *status; int N; int M;};
static int CheckFull(ST st, int i);
static int CheckDeleted(ST st, int i);
probing uniforme.
0 A
1 start = h(’R’) = 82 % 13 = 4 collisione
2 index = (4+1+12) % 13 = 6
3
4 E
5
R 6 R
7
8
9
10
11
12
A.A. 2020/21 13 Le tabelle di hash 61
A E R C N P
h(k) = 0 4 4 2 0 2
0 A 0 A
1 1 start = h(’N’) = 78 % 13 = 0 collisione
2 C 2 C
3 3
index = (0+1+12) % 13 = 2 collisione
4 E 4 E index = (0+2+22) % 13 = 6 collisione
5 5 index = (0+3+32) % 13 = 12
C 6 R N 6 R
7 7
8 8
9 9
10 10
11 11
12 12 N
A.A. 2020/21 13 Le tabelle di hash 62
A E R C N P
h(k) = 0 4 4 2 0 2
0 A
1 start = h(’P’) = 80 % 13 = 2 collisione
2 C
3
index = (2+1+12) % 13 = 4 collisione
4 E index = (2+2+22) % 13 = 8
5
P 6 R
7
8 P
9
10
11
12 N
A.A. 2020/21 13 Le tabelle di hash 63
Double hashing
Insert:
calcola i = h1(k)
se posizione libera, inserisci chiave,
altrimenti calcola j = h2(k) e prova in
i = (i + j) % M
ripeti fino a cella vuota. Ricordare che, se
M = 2*max, < 1
Esempi di h1 e h2:
h1(k) = k % M e M primo
h2(k) = 1 + k%97
h2(k) non ritorna mai 0 e h2%M non ritorna
mai 0 se M > 97.
A.A. 2020/21 13 Le tabelle di hash 65
static int hash1(Key k, int M) {
int h = 0, base = 127;
for ( ; *k != '\0'; k++) h = (base * h + *k) % M;
return h;
}
static int hash2(Key k, int M) {
int h = 0, base = 127;
for ( ; *k != '\0'; k++) h = (base * h + *k);
h = ((h % 97) + 1);
return h;
}
void STinsert(ST st, Item item) {
int i = hash1(KEYget(&item), st->M);
int j = hash2(KEYget(&item), st->M);
while (full(st, i))
i = (i+j)%st->M;
st->a[i] = item;
st->N++;
}
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A 0 A 0 A
1 1 1
2 2 2 NB: non si rispetta
3 3 3
4 4 4 E il vincolo < ½
5 5 S 5 S
A 6 S 6 E 6
7 7 7
8 8 8
9 9 9
10 10 10
11 11 11
12 12 12
A.A. 2020/21 13 Le tabelle di hash 69
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A
1 i = h(’R’) = 82 % 13 = 4 collisione
2 j = (82 % 97 +1) % 13) = 5
3 i = (4 + 5) % 13 = 9
4 E
5 S
R 6
7
8
9 R
10
11
12
A.A. 2020/21 13 Le tabelle di hash 70
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A 0 A 0 A
1 1 1
2 C 2 C 2 C
3 3 3
4 E 4 E 4 E
5 S 5 S 5 S
C 6 H 6 I 6
7 7 H 7 H
8 8 8 I
9 R 9 R 9 R
10 10 10
11 11 11
12 12 12
A.A. 2020/21 13 Le tabelle di hash 71
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A i = h(’N’) = 78 % 13 = 0 collisione
1 N
2
j = (78 % 97 +1) % 13) = 1
C
3 i = (0 + 1) % 13 = 1
4 E
5 S
N 6
7 H
8 I
9 R
10
11
12
A.A. 2020/21 13 Le tabelle di hash 72
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A 0 A 0 A
1 N 1 N 1 N
2 C 2 C 2 C
3 3 3
4 E 4 E 4 E
5 S 5 S 5 S
G 6 G X 6 G M 6 G
7 H 7 H 7 H
8 I 8 I 8 I
9 R 9 R 9 R
10 10 X 10 X
11 11 11
12 12 12 M
A.A. 2020/21 13 Le tabelle di hash 73
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A
1 N i = h(’P’) = 80 % 13 = 2 collisione
2 C j = (80 % 97 +1) % 13) = 3
3 i = (2 + 3) % 13 = 5 collisione
4 E i = (5 + 3) % 13 = 8 collisione
5 S
P 6 G i = (8 + 3) % 13 = 11
7 H
8 I
9 R
10 X
11 P
12 M
A.A. 2020/21 13 Le tabelle di hash 74
A S E R C H I N G X M P
h1(k)= 0 5 4 4 2 7 8 0 6 10 12 2
0 A In inserzione c’è stata collisione 0 A
1 N tra ’P’ e ’C’. Non ci sono state 1 N
2 C 2 P
3
altre collisioni. 3
4 E Se si cancella ’C’, ’P’ prende 4 E
5 S il suo posto. 5 S
P 6 G P 6 G
7 H 7 H
8 I 8 I
9 R 9 R
10 X 10 X
11 P 11
12 M 12 M
A.A. 2020/21 13 Le tabelle di hash 75
Complessità del double hashing
Ipotesi:
hashing semplice uniforme
probing uniforme.
Tabelle di hash
Cormen 12.1, 12.2, 12.3, 12.4
Sedgewick 14.1, 14.2, 14.3, 14.4