algoritmi e programmazione avanzata - politecnico di...
TRANSCRIPT
1
1/296
Algoritmi e Programmazione Avanzata - teoria
2/296
Che cosa c’è nella lezione
Questa lezione si occupa di strutture dati:
tipi di dato astratto
le pile
le code
le liste
gli alberi binari di ricerca
le tabelle di hash.
2
3/296
Algoritmi e Programmazione Avanzata - teoria
4/296
Tipo di Dato Astratto:
Definizione
Modello matematico sul quale è definito un insieme di operazioni.
3
5/296
Modello: insieme di elementi genericiOperazioni:
unione (X,Y)inters (X,Y)diff (X,Y)
Modello: intervallo di interiOperazioni:
+-*:
Esempio
6/296
Tipi primitivi: quelli supportati da un linguaggio (int, float, char per il C) con le loro operazioni (+, -, *, /, % etc.).
Tipi di Dati Astratti : estensione dell’insieme dei tipi di dato supportati.
Estensione dei tipi primitivi
4
7/296
nuove operazioni sui tipi primitivinuove operazioni su nuovi tipi
Tipi di Dato Astratto: associazione nuovo tipo ↔ nuovo insieme di operazioni.
Operatori: predefiniti, operazioni elementari sui tipi primitivi.
Procedure come estensione degli operatori:
Estensione
8/296
Definizione del Tipo di Dato Astratto indipendente da:
linguaggio di programmazione
scelta implementativa (struttura dati)
Implementazione
5
9/296
Definire in un file separato le procedure corrispondenti alle operazioni definite dal Tipo di Dato Astratto.
Definire un tipo di dato corrispondente al Tipo di Dato Astratto.
Lavorare sul Tipo di Dato Astratto esclusivamente utilizzando le procedure fornite.
Campi dato visibili solo attraverso le funzioni.
Implementazione in C
10/296
Esempio
Definizione del tipo:typedef SET_ELEM int;
Esempi di procedure:SET_ELEM *unione (SET_ELEM *, SET_ELEM *);SET_ELEM *inters(SET_ELEM *, SET_ELEM *);SET_ELEM *diff(SET_ELEM *, SET_ELEM *);SET_ELEM *make_null(void);int size (SET_ELEM *); void dump (SET_ELEM *);
6
11/296
Algoritmi e Programmazione Avanzata - teoria
12/296
Tipo di dato astratto con politica LIFO (Last In First Out) con operazioni:
Push: inserisce nuovo elemento nella pilaPop: estrae dalla pila l’ultimo elementoinseritoEmpty: vero se pila vuotaInit: crea nuova pila
Definizione
7
13/296
Esempio
Init()
14/296
Esempio
Push (K1)
K1
8
15/296
Esempio
Push (K2)
K1
K2
16/296
Esempio
Push (K3)
K1
K3
K2
9
17/296
Esempio
Pop
K1
K2 K3
18/296
Esempio
Pop
K1
K2
10
19/296
Vettore buff di N elementi
Variabile top: indice dell’ultimo elemento inserito
Complessità delle operazioni T(n) = O(1)
Implementazione tramite vettore
20/296
#define N 100int buff[N];int top;void push(int val);int pop(void);int empty(void);void push(int val) {
buff[++top] = val;return;
}
Implementazione C 1/2
11
21/296
int pop(void) {
return(buff[top--]);}int empty(void){
if(top == 0)return (1);
elsereturn (0);
}
Implementazione C 2/2
22/296
Algoritmi e Programmazione Avanzata - teoria
12
23/296
Tipo di dato astratto con politica FIFO (First In First Out) con operazioni:
Enqueue: inserisce un nuovo elementonella codaDequeue: estrae dalla coda il primo elemento inserito Empty: vero se coda vuotaInit: crea nuova coda.
Definizione
24/296
Esempio
Init()
Dequeue Enqueue
13
25/296
Esempio
K1
Dequeue Enqueue
Enqueue(K1)
26/296
Esempio
K1
Dequeue Enqueue
Enqueue(K2) K2
14
27/296
Esempio
K1
Dequeue Enqueue
Enqueue(K3) K2 K3
28/296
Esempio
K2
Dequeue Enqueue
K3K1Dequeue
15
29/296
Esempio
K3
Dequeue Enqueue
K2Dequeue
30/296
Vettore buffer di N+1 elementi per code di Nelementi
Variabili:head: indice del primo elemento inseritotail: indice del primo elemento disponibileper l’inserimento
Vettore come buffer circolare
Complessità delle operazioni T(n) = O(1)
Implementazione tramite vettore
16
31/296
Dequeue: incrementa head modulo N+1
Enqueue: incrementa tail modulo N+1
Inizialmente head = 0, tail = 0
Coda piena (overflow):head = (tail + 1) modulo N+1
Coda vuota (underflow):head = tail
Buffer circolare
32/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
head tail
Coda vuota
17
33/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
head tail
Enqueue(A)
34/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(A)
A
head tail
18
35/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(B)
A
tailhead
36/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(B)
A
tail
B
head
19
37/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(C)
A
tail
B
head
38/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(C)
A B
tailhead
20
39/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(D)
A B
tailhead
40/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(D)
A B
tail
D
head
21
41/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
A B
tail
D
head
42/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
B
head tail
DA
22
43/296
Esempio
C
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(E)
B
head tail
D
44/296
Esempio
C E
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(E)
B
head tail
D
23
45/296
Esempio
C E
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(F)
B
head tail
D
46/296
Esempio
C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(F)
B
head
D
tail
Coda piena
24
47/296
Esempio
C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
B
head
D
tail
48/296
Esempio
C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
head
D
tail
B
25
49/296
Esempio
C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(G)
head
D
tail
50/296
Esempio
G C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Enqueue(G)
head
D
tail Coda piena
26
51/296
Esempio
G C E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
head
D
tail
52/296
Esempio
G E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
head
D
tail
C
27
53/296
Esempio
G E F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
headtail
D
54/296
Esempio
G F
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
headtail
E
28
55/296
Esempio
G
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
head tail
F
56/296
Esempio
1 2 3 4 50
Coda con max 5 elementi (N=5)
Dequeue
G
head tailCoda vuota
29
57/296
Implementazione in C
#define DIM 10int buffer[DIM+1];int tail=0, head=0;
int enqueue(int elem);int dequeue(void);int empty(void);
58/296
Implementazione in C
int enqueue(int elem){if((tail+1)==head||(tail==DIM && head==0))return(-1);
buffer[tail++] = elem;if(tail == (DIM+1))tail = 0;
return(0);}
30
59/296
Implementazione in C
int dequeue(void){int ret;if(head == tail)
return(-1);ret = buffer[head++];if(head == (DIM+1))
head = 0;return(ret);
}
60/296
Implementazione in C
int empty(void){
if(head == tail)return(1);
elsereturn(0);
}
31
61/296
Algoritmi e Programmazione Avanzata - teoria
62/296
Struttura dati lineare:elementi allocati/deallocati separatamenteelementi concatenati (e quindi accessibili) attraverso puntatorivariabile head: accesso al primo elementooperazioni:
- insert (in testa di linea non ordinata o in lista ordinata)
- search- delete
Definizione
32
63/296
Vantaggi/svantaggi:
memoria corrispondente agli elementieffettivamente utilizzataaccesso mediante scansione
Classificazione:
liste ordinate / non ordinate
Definizione
64/296
Operazioni:Insert(L, k): nserisce una chiave k nella lista L
- liste non ordinate: in testa
- liste ordinate: posizione corretta
Search(L, k): cerca la chiave k nella lista L Delete(L, x): cancella la chiave k dalla lista L dato il puntatore x all’elemento che la contiene.
Definizione
33
65/296
Esempio
head(L)
key nextLista concatenata doppia
head(L) NIL
key nextLista concatenata semplice
NILNIL
previous
66/296
Inserimento in testa (lista non ordinata)
head(L) Z P NIL
34
67/296
Inserimento in testa (lista non ordinata)
head(L) Z P NIL
A NILxinsert(L, x)
68/296
Inserimento in testa (lista non ordinata)
head(L)
Z P NIL
A next(x) = head(L)head(L) = x
35
69/296
Implementazione C
struct e {int key;struct e *next;};
struct e *insert(struct e *pTop,int val);
struct e *search(struct e *pTop,int *val,int *status);
struct e *newE( );
70/296
Implementazione C
struct e *newE ( )
36
71/296
Implementazione C
struct e *newE ( )
Allocazione di un nuovo nodo
72/296
Implementazione C
struct e *newE ( ){
struct e *ePtr;
ePtr = (struct e *) malloc (sizeof(struct e));
if (ePtr==NULL) {fprintf (stderr, "Allocazione
fallita.");exit (FAILURE);
}return (ePtr);
}
37
73/296
Implementazione C
struct e *insert (struct e *pTop,int val)
74/296
Implementazione C
struct e *insert (struct e *pTop,int val)
Inserimento in testa
38
75/296
Implementazione C
struct e *insert (struct e *pTop,int val){
struct e *pNew;
pNew = newE ();
pNew->key = val;pNew->next = pTop;
76/296
Implementazione C
struct e *insert (struct e *pTop,int val){
struct e *pNew;
pNew = newE ();
pNew->key = val;pNew->next = pTop;
next(x) = head(L)
39
77/296
Implementazione C
struct e *insert (struct e *pTop,int val){
struct e *pNew;
pNew = newE ();
pNew->key = val;pNew->next = pTop;pTop = pNew;
78/296
Implementazione C
struct e *insert (struct e *pTop,int val){
struct e *pNew;
pNew = newE ();
pNew->key = val;pNew->next = pTop;pTop = pNew;
head(L) = x
40
79/296
Implementazione C
struct e *insert (struct e *pTop,int val){
struct e *pNew;
pNew = newE ();
pNew->key = val;pNew->next = pTop;pTop = pNew;
return (pTop);}
80/296
Ricerca
Scansione della lista a partire da head
Confronto chiave cercata / chiave corrente
Terminazione:
trovata la chiave cercata
fine lista
41
81/296
Implementazione C
struct e *search (struct e *pTop,int *val,int*status)
82/296
Implementazione C
struct e *search (struct e *pTop,int *val,int*status) ricerca
42
83/296
Implementazione C
struct e *search (struct e *pTop,int *val,int*status){
struct e *pTmp;*status = FAILURE;pTmp=pTop;while ((pTmp!=NULL) && (*status==FAILURE))
{if (pTmp->key==*val) {
*status = SUCCESS;} else {
pTmp=pTmp->next;}
}
84/296
Implementazione C
if (*status==SUCCESS) {fprintf (stdout,"Trovato %d\n",pTmp->key);
} else {fprintf (stdout,"NON Trovato \n");
}
return (pTop);}
43
85/296
Cancellazione
Richiede:
una ricerca, che produce il puntatore x all'elemento da cancellare
il riaggiustamento dei puntatori- all’elemento da cancellare- all’elemento precedente- all’elemento seguente (lista concatenata doppia)
86/296
Cancellazione
head(L) NILNIL P A Z
44
87/296
Cancellazione
head(L) NILNIL P A Z
delete(L, x) x
88/296
Cancellazione
prev[next[x]] = prev[x]next[prev[x]] = next[x]
head(L) NILNIL P A Z
45
89/296
Complessità
Inserzione in testa di lista non ordinata:T(n) = O(1)
Ricerca:T(n) = O(n)
Cancellazione (dato il puntatore all’elemento da cancellare):
T(n) = O(1)
90/296
Algoritmi e Programmazione Avanzata - teoria
46
91/296
Tipo di dato astratto con operazioni:searchminimummaximumpredecessorsuccessorinsertdelete
Implementano dizionari e code prioritarie.
Definizione 1/2
92/296
Proprietà:∀nodo x vale che:
∀ nodo y ∈Left(x), key[y] ≤ key[x]∀ nodo y ∈Right(x), key[y] ≥ key[x]
Definizione 2/2
≤ ≥Left(x) Right(x)
x
47
93/296
Esempi
5
3 7
2 4 8
5
3
7
2
4
8
94/296
Attraversamenti
Attraversamento: elenco dei nodi secondo una strategia:
Pre-ordine: x, Left(x), Right(x)In-ordine: Left(x), x, Right(x) Post-ordine: Left(x), Right(x), x
Complessità: T(n) = Θ(n)
Attraversamento in-ordine: ordinamento crescente delle chiavi.
48
95/296
Esempio
15
6 18
17 203 7
2 4 13
9
96/296
Esempio
15
6 18
17 203 7
2 4 13
9
15Visita in pre-ordine
1
49
97/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
2
1
Visita in pre-ordine
6
98/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
3
2
1
Visita in pre-ordine
63
50
99/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
2
1
Visita in pre-ordine
632
100/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
1
Visita in pre-ordine
6324
51
101/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
1
Visita in pre-ordine
63247
102/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
7
1
Visita in pre-ordine
6324713
52
103/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
8
7
1
Visita in pre-ordine
63247139
104/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
8
7
1
9
Visita in pre-ordine
6324713918
53
105/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
8
7
1
10
9
Visita in pre-ordine
632471391817
106/296
Esempio
15
6 18
17 203 7
2 4 13
9
15
4
3
5
2
6
8
7
1
10
9
11
Visita in pre-ordine
63247139181720
54
107/296
Esempio
15
6 18
17 203 7
2 4 13
9
Visita in-ordine
108/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
Visita in-ordine
55
109/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
Visita in-ordine
3
110/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
Visita in-ordine
34
56
111/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
Visita in-ordine
346
112/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
Visita in-ordine
3467
57
113/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
Visita in-ordine
34679
114/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
7
Visita in-ordine
3467913
58
115/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
7
8
Visita in-ordine
346791315
116/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
7
8
9
Visita in-ordine
34679131517
59
117/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
7
8
10
9
Visita in-ordine
3467913151718
118/296
Esempio
15
6 18
17 203 7
2 4 13
9
2
1
2
3
4
5
6
7
8
10
9 11
Visita in-ordine
346791315171820
60
119/296
Esempio
15
6 18
17 203 7
2 4 13
9
Visita in post-ordine
120/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
Visita in post-ordine2
61
121/296
Esempio
15
6 18
17 203 7
2 4 13
9
1 2
Visita in post-ordine24
122/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
Visita in post-ordine243
62
123/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
4
Visita in post-ordine2439
124/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
4
5
Visita in post-ordine243913
63
125/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
6
4
5
Visita in post-ordine2439137
126/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
7
6
4
5
Visita in post-ordine24391376
64
127/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
7
6
4
5
8
Visita in post-ordine2439137617
128/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
7
6
4
5
98
Visita in post-ordine243913761720
65
129/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
7
6
4
5
9
10
8
Visita in post-ordine24391376172018
130/296
Esempio
15
6 18
17 203 7
2 4 13
9
1
3
2
7
6
4
5
9
10
8
11
Visita in post-ordine2439137617201815
66
131/296
Search
Ricerca ricorsiva di un nodo con chiave k:
percorrimento dell’albero dalla radice;
terminazione: trovato k oppure giunti a una foglia;
ricorsione: dal nodo x - su sottoalbero sinistro se k < key[x] - su sottoalbero destro se k ≥ key[x].
132/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
67
133/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
134/296
Esempio
15
18
17 20
k = 1313 ≠ 15
6
3 7
2 4 13
9
68
135/296
Esempio
15
18
17 20
k = 1313 ≠ 1513 < 15
6
3 7
2 4 13
9
136/296
Esempio
15
18
17 20
k = 1313 ≠ 1513 < 15
6
3 7
2 4 13
9
69
137/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
138/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
70
139/296
Esempio
15
18
17 20
k = 1313 ≠ 6
6
3 7
2 4 13
9
140/296
Esempio
15
18
17 20
k = 1313 ≠ 613 > 6
6
3 7
2 4 13
9
71
141/296
Esempio
15
18
17 20
k = 1313 ≠ 613 > 6
6
3 7
2 4 13
9
142/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
72
143/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
144/296
Esempio
15
18
17 20
k = 1313 ≠ 7
6
3 7
2 4 13
9
73
145/296
Esempio
15
18
17 20
k = 1313 ≠ 713 > 7
6
3 7
2 4 13
9
146/296
Esempio
15
18
17 20
k = 1313 ≠ 713 > 7
6
3 7
2 4 13
9
74
147/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
148/296
Esempio
15
18
17 20
k = 13
6
3 7
2 4 13
9
75
149/296
Esempio
15
18
17 20
k = 1313=13
6
3 7
2 4 13
9
150/296
Esempio
15
18
17 20
k = 1313=13
6
3 7
2 4 13
9 Trovato!
76
151/296
Min e max
Min:seguire il puntatore al sottoalbero sinistro finchè esiste.
Max:seguire il puntatore al sottoalbero destro finchèesiste.
152/296
Esempio
15
6 18
17 203 7
2 4 13
9
77
153/296
Esempio
15
6 18
17 203 7
2 4 13
9
154/296
Esempio
15
6 18
17 203 7
2 4 13
9
78
155/296
Esempio
15
6 18
17 203 7
2 4 13
9
min = 2
156/296
Esempio
15
6 18
17 203 7
2 4 13
9
min = 2
79
157/296
Esempio
15
6 18
17 203 7
2 4 13
9
min = 2max = 20
158/296
Successor
Successore di un nodo x:nodo con la più piccola chiave k > key[x].Due casi:
∃ Right(x): succ(x) = min(Right(x))∃ Right(x): succ(x) = primo antenato di x ilcui figlio sinistro è anche un antenato di x.
x
p[x]
x
p[x]
80
159/296
Esempio
15
6 18
17 203 7
2 4 13
9
160/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
81
161/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
162/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
82
163/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
succ(x)
164/296
Esempio
15
6 18
17 203 7
2 4 13
9
83
165/296
Esempio
15
6 18
17 203 7
2 4 13
9x
166/296
Esempio
15
6 18
17 203 7
2 4 13
9x
84
167/296
Esempio
15
6 18
17 203 7
2 4 13
9x
succ(x)
168/296
Predecessor
Predecessore di un nodo x:nodo con la più grande chiave k < key[x].
Due casi:
∃ Left(x): pred(x) = max(Left(x))
∃ Left(x): pred(x) = primo antenato di x il cui figlio destro è anche un antenato di x.
85
169/296
Esempio
15
6 18
17 203 7
2 4 13
9
170/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
86
171/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
172/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
87
173/296
Esempio
15
6 18
17 203 7
2 4 13
9
x
pred(x)
174/296
Esempio
15
6 18
17 203 7
2 4 13
9
88
175/296
Esempio
15
6 18
17 203 7
2 4 13
9 x
176/296
Esempio
15
6 18
17 203 7
2 4 13
9 x
89
177/296
Esempio
15
6 18
17 203 7
2 4 13
9 x
pred(x)
178/296
Insert
Inserire in un albero binario di ricerca un nodo z con chiave key[z] ⇒ mantenimento della proprietà:
creazione del nuovo nodo z, con Left[z]=Right[z]=NIL;
posizione di inserimento di z come foglia, simulando la ricerca di key[z];
aggiornamento dei puntatori.
90
179/296
Esempio
insert(T,z)
z12
5 18
15 202 9
17
13
T
180/296
Esempio
insert(T,z)
z12
5 18
15 202 9
17
13
T
91
181/296
Esempio
insert(T,z)
z12
5 18
15 202 9
17
13
T
182/296
Esempio
z12
5 18
15 202 9
17
13
T insert(T,z)
92
183/296
Esempio
z12
5 18
15 202 9
17
13
T insert(T,z)
184/296
Esempio
z12
5 18
15 202 9
17
13
T insert(T,z)
93
185/296
Esempio
12
5 18
15 202 9
1713
T
186/296
Delete
Cancellazione da un albero binario di ricerca di un nodo z ⇒
mantenimento della proprietàmantenimento della struttura ad alberobinario.
Tre casi:1. nodo z foglia2. nodo z con 1 solo figlio 3. nodo z con 2 figli.
94
187/296
Caso 1: foglia
15
6 18
17 203 7
2 4 13
9 z
188/296
Caso 1: foglia
15
6 18
17 203 7
2 4 13
9 z
delete(z):rimozione immediata.
95
189/296
Caso 1: foglia
15
6 18
17 203 7
2 4 13
190/296
Caso 2: 1 figlio
15
6 18
17 203 7
2 4 13
9
delete(z):
z
96
191/296
Caso 2: 1 figlio
15
6 18
17 203 7
2 4 13
9
delete(z):
x
z
192/296
Caso 2: 1 figlio
15
6 18
17 203 7
2 4 13
9
x
p
delete(z):il figlio x di z diventafiglio del padre p di z.
z
97
193/296
Caso 2: 1 figlio
15
6 18
17 203
2 4 13
9
194/296
Caso 3: 2 figli
15
6 18
17 203 7
2 4 13
9
delete(z):z
98
195/296
Caso 3: 2 figli
15
6 18
17 203 7
2 4 13
9
y
delete(z):si cancella y = succ(z)z
196/296
Caso 3: 2 figli
15
6 18
17 203 7
2 4 13
9
y
delete(z):si cancella y = succ(z)si copia y su z
z
99
197/296
Caso 3: 2 figli
15
6 18
17 203 7
2 4 13
9
y
delete(z):si cancella y = succ(z)si copia y su z
z
Nota: y può esserepred(z)
198/296
Caso 3: 2 figli
17
6 18
203 7
2 4 13
9
100
199/296
Complessità
Le operazioni hanno complessità T(n) = O(h):
albero con n nodi completamente bilanciato- altezza h = log2 n
albero con n nodi completamente sbilanciato- altezza h = n
O(log2 n) ≤ T(n) ≤ O(n)
200/296
101
201/296
Tipo di dato astrattoModello: insieme finito di simboli. Operazioni:
searchinsertdelete.
? ∃ corrispondenza biunivoca insieme finito di simboli
e intervallo di interi.
Dizionario
202/296
Applicazioni
Tabella dei simboli di un compilatore
Chiave = nome di un identificatoreDati aggiuntivi = tipo, contesto, dichiarazione.
Cache di file o URL
Chiave = pathDati aggiuntivi = attributi e contenuto.
102
203/296
Chiave k ∈ U = {0, 1, …, m-1}
Tutte le chiavi sono distinte.
Vettore T[0, 1, …, m-1]:se ∃ k, T[k] punta a k, altrimenti T[k] = NIL.
Memorizzazione di un insieme K di |K| chiavi.
Tabelle ad accesso diretto 1/2
204/296
Tabelle ad accesso diretto 2/2
U (universo delle chiavi)
K (chiavi usate)
•7•4 •9
•5•3•8
•6
•0
•1
•2
012345678
m-1
23
5
8
chiave k
dati associati
T
x
103
205/296
Operazioni
Search(T, k)
return(T[k])
Insert(T, x)
T[key[x]] = x
Delete(T, x)
T[key[x]] = NIL
206/296
Vantaggi/svantaggi
Complessità delle operazioni: T(n) = O(1)
Occupazione di memoria S(n) = O(|U|) = O(m)
applicabile per m piccolospreco di memoria per |K| << m.
104
207/296
Tabelle di hash
In generale:m grande (vettore T non allocabile)|K| << m.
Tabella di hash:tipo di dato astratto con occupazione di spazio O(|K|) e tempo medio di accesso O(1).
208/296
Funzione di hash 1/2
La tabella di hash contiene |K| elementi (|K|<<|U|)
Funzione di hash h: mappa una chiave k in una posizione del vettore h(k)
h: U → { 0, 1, ..., m-1 }
Elemento x viene memorizzato nella locazione T[h(key[x])]
105
209/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
210/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
h(k1)
106
211/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
h(k1)
h(k2)
212/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
h(k1)
h(k2)
h(k3)
107
213/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
h(k1)h(k4)
h(k2)
h(k3)
214/296
Funzione di hash 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
h(k1)h(k4)
h(k5)=h(k2)
h(k3)
Collisione
108
215/296
Progetto della funzione di hash 1/2
Funzione ideale
hashing uniforme semplice:se le chiavi k sono equiprobabili, allora i valori di h(k) devono essere equiprobabili.
∑=
−==jkhk
mjm
kP)(:
1,,1,0,1
)( K
216/296
Progetto della funzione di hash 2/2
In pratica:
k non sono equiprobabili, anzi correlate:- usare tutti i bit della chiave- “amplificare” le differenze.
chiavi come numeri interi (illimitati)- “abc” diventa ‘a’*2562 + ‘b’*256 + ‘c’.
109
217/296
Metodi
Divisione:
h(k) = k mod m
m: primo non troppo vicino a potenza di 2.
Evitare che m sia:- potenza di 2 (usa solo gli ultimi m bit di k);- una potenza di 10 (se i k sono numeri
decimali);- 2p-1 (per stringhe di caratteri in base 2p,
trasposizioni di caratteri ⇒ collisioni).
218/296
Esempio 1/2
n = 2000 elementi previsti
numero di confronti medio pari a 3 nelle ricerche
m = 701: numero primo vicino a 2000/3 ma distante dalle potenze di 2
h(k) = k mod 701
110
219/296
Esempio 2/2
Moltiplicazione:data costante 0<A<1h(k) = m ⋅ (k⋅A - k⋅A)k⋅A “rimescola” i bit i km ⋅ (k⋅A - k⋅A) espande l’intervallo [0,1]nell’intervallo [0,m].
Scelta:m potenza di 2 (estrazione di sotto-sequenzadi bit);A = (√5 – 1) / 2 = 0.6180339887.
220/296
Collisione
Definizione: collisione: h(ki)=h(kj) per ki ≠ kj
Le collisioni sono inevitabili, occorre:minimizzarne il numero (buona funzione dihash);gestirle:- linear chaining- open addressing.
111
221/296
Linear Chaining 1/2
Più elementi possono risiedere nella stessa locazione della tabella T ⇒ lista concatenata.
Operazioni:inserimento in testa alla listaricerca nella listacancellazione dalla lista.
222/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
•k6
112
223/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k1
•k6
224/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k1
k2
•k6
113
225/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k1
k3
k2
•k6
226/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k1
k4
k3
k2
•k6
114
227/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k1
k4
k3
k5 k2
•k6
228/296
Linear Chaining 2/2
•k1
012345678
m-1
T
U
•k3
•k2
•k4
•k5
k6
k4
k3
k5 k2
•k6
k1
115
229/296
Complessità 1/2
Ipotesi:Liste non ordinate:
n = numero di elementi memorizzatim = dimensione della tabella di hash.
Hashing semplice uniforme: h(k) ha egual probabilità di generare gli m valori di uscita.
Definizionefattore di carico α=n/m (>, = o < 1)
230/296
Complessità 2/2
Inserimento: T(n) = O(1)
Ricerca: caso peggiore T(n) = Θ(n)caso medio T(n) = O(1+α)
Cancellazione:T(n) = O(1) se disponibile il puntatore ad xe la lista è doppiamente linkata;come la ricerca se disponibile il valore di x,oppure il valore della chiave k, oppure lalista è semplicemente linkata.
116
231/296
Ogni cella di T può contenere un soloelemento.
Tutti gli elementi sono memorizzati in T.
Collisione: ricerca di cella non ancora occupata mediante probing:
generazione di una permutazione dellecelle = ordine di ricerca della cella libera.
h(k, i) : U × { 0,1,...,m-1 } → { 0,1,...,m-1 }
Open addressing
α≤1
chiave tentativo (0…m-1)
232/296
Funzioni di probing
Linear probingh(k, i) = (h’(k)+i) mod m
Double hashingh(k, i) = (h1(k)+ i h2(k) ) mod m dove:
h1(k) = k mod mh2(k) = 1 + (k mod m’) m’= m-1 o m-2
Quadratic probingh(k, i) = (h’(k)+ c1i + c2i2) mod m c1 e c2 ≠ 0
117
233/296
Operazioni 1/2
Insert:tentativo i=0calcola h(k, i)se libero, inserisci chiave, altrimenti incrementa iripeti fino a i=m
Search:tentativo i=0calcola h(k, i)se trovata chiave, termina con successoincrementa iripeti fino a i=m o cella vuota (insuccesso).
234/296
Operazioni 2/2
Delete:operazione complessa che interrompe le catene di collisione.
L’open addressing è in pratica utilizzato solo quando non si deve mai cancellare.
118
235/296
Complessità
Ipotesi:hashing semplice uniformeprobing uniforme.
Tentativi di “probing”:per l’inserimento: 1/(1–α)per la ricerca:
- senza successo: 1/(1–α)- con successo: 1/α ln (1/(1- α)) + 1/ α
236/296
Esempio 1
Inserimento delle chiavi
10, 22, 31, 4, 15, 28, 17, 88, 59
in tabella con m=11 con open addressing.
119
237/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
238/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
0123456789
10
120
239/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
10
0123456789
10
240/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
10
0123456789
10
121
241/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
0123456789
10
242/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
4
0123456789
10
122
243/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
4
0123456789
10
Collisione:h(15, 0) = 4
244/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
154
0123456789
10
Collisione:h(15, 1) = 5
123
245/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
28154
0123456789
10
246/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
28154
0123456789
10
Collisione:h(17, 0) = 6
124
247/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
0123456789
10
Collisione:h(17, 1) = 7
248/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
0123456789
10
Collisione:h(88, 0) = 0
125
249/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
880123456789
10
Collisione:h(88, 1) = 1
250/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
880123456789
10
Collisione:h(59, 0) = 4
126
251/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
880123456789
10
Collisione:h(59, 1) = 5
252/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
880123456789
10
Collisione:h(59, 2) = 6
127
253/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031
1728154
880123456789
10
Collisione:h(59, 3) = 7
254/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031591728154
880123456789
10
Collisione:h(59, 4) = 8
128
255/296
Esempio 1
10, 22, 31, 4, 15, 28, 17, 88, 59
Linear probingh(k, i) = (k mod 11 + i) mod 11
22
1031591728154
88
primaryclustering
0123456789
10
256/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
129
257/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
10
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
258/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
10
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
130
259/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
260/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
131
261/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Collisione:h(15, 0) = 4
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
262/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
4
0123456789
10
Collisione:h(15, 1) = 8
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
132
263/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
264/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(17, 0) = 6
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
133
265/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(17, 1) = 10
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
266/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(17, 2) = 9
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
134
267/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(17, 3) = 3
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
268/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 0) = 0
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
135
269/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 1) = 4
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
270/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 2) = 3
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
136
271/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 3) = 8
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
272/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 4) = 8
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
137
273/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 5) = 3
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
274/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 6) = 4
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
138
275/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 7) = 0
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
17
276/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(88, 8) = 2
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
1788
139
277/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(59, 0) = 4
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
8817
278/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
103115
28
4
0123456789
10
Collisione:h(59, 1) = 8
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
8817
140
279/296
Esempio 2
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031155928
4
0123456789
10
Collisione:h(59, 2) = 7
Quadratic probingh(k, i) = (k mod 11+i+3i2) mod 11
8817
280/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
141
281/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
10
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
282/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
10
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
142
283/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
284/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
143
285/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Collisione:h(15, 0) = 4
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
286/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Collisione:h(15, 1) = 10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
144
287/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
4
0123456789
10
Collisione:h(15, 2) = 5
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
15
288/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
28
4
0123456789
10
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
15
145
289/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
28
4
0123456789
10
Collisione:h(17, 0) = 6
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
15
290/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
28
4
0123456789
10
Collisione:h(17, 1) = 3
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
146
291/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
28
4
0123456789
10
Collisione:h(88, 0) = 0
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
292/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
28
4
0123456789
10
Collisione:h(88, 1) = 9
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
147
293/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
8828
4
0123456789
10
Collisione:h(88, 2) = 7
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
294/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
8828
4
0123456789
10
Collisione:h(59, 0) = 4
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
148
295/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
8828
4
0123456789
10
Collisione:h(59, 1) = 3
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15
296/296
Esempio 3
10, 22, 31, 4, 15, 28, 17, 88, 59
22
1031
8828
4
59
0123456789
10
Collisione:h(59, 2) = 2
Double hashingh(k, i) = (k mod 11+i(1+k mod 10)) mod 11
17
15