Problema:
• Progettare strutture dati che supportino efficienti algoritmi di ricerca in
insiemi dinamici, (ovvero in insiemi la cui composizione puó variare nel
tempo (ad es., a causa di inserimenti di nuovi elementi, o cancellazioni di
vecchi elementi, etc.)
Operazioni di cui siamo interessati:
• Interrogazioni: ritornano informazioni circa l’insieme S
- S EARCH(S, k)
- M INIMUM(S), M AXIMUM(S)
- S UCCESSORE(S, x), P REDECESSORE(S, x)
• Operazioni di modifica: cambiano la composizione dell’insieme S
- I NSERT(S, x)
- D ELETE(S, x)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 1/20
Semplici strutture dati per il supporto delle operazioni
• Array ordinato:
- S EARCH(S, k) puó essere eseguita in tempo O(log n)
- S UCCESSORE(S, x), P REDECESSORE(S, x) parimenti in tempo
O(log n)
- I NSERT(S, x), D ELETE(S, x) in tempo O(n)
• Lista a puntatori:
- S EARCH(S, k) viene eseguita in tempo O(n)
- S UCCESSORE(S, x), P REDECESSORE(S, x) parimenti in tempo O(n)
- I NSERT(S, x), D ELETE(S, x) in tempo O(1)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 2/20
Alberi binari di ricerca
• Supportano molte delle tipiche operazioni su insiemi dinamici:
- S EARCH(S, k), S UCCESSORE(S, x), P REDECESSORE(S, x),
I NSERT(S, x), D ELETE(S, x), M INIMO(S), M ASSIMO(S), ...
• Il tempo di esecuzione di queste operazioni é O(h), dove h é l’altezza
dell’albero binario di ricerca
- nel caso peggiore: O(n)
- nel caso medio: O(log n)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 3/20
Ripasso di nozioni su alberi
• Rappresentazione di alberi:
- una struttura linkata in cui ciascun nodo é un oggetto
• Rappresentazione di nodi:
- campo chiave (contiene key[v])
- campo dati (contiene i dati satelliti)
- Left: puntatore al figlio sinistro
- Right: puntatore al figlio destro
- Parent: puntatore al padre
padre
L
R
chiave
figlio sinistro
dati
figlio destro
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 4/20
Alberi binari di Ricerca
• Alberi binari con la proprietá addizionale:
- se il nodo y é nel sottoalbero sinistro del nodo x allora
key[y] ≤ key[x]
- se il nodo y é nel sottoalbero destro del nodo x allora
key[y] ≥ key[x]
x
≤x
≥x
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 5/20
Esempi di alberi binari di ricerca
5
7
3
2
2
5
3
7
8
5
8
5
Dagli esempi si vede che differenti alberi di ricerca possono rappresentare
lo stesso insieme.
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 6/20
Operazioni in alberi binari di ricerca: S EARCH(S, k)
• Idea: partendo con u =radice dell’albero, confronta k con key[u],
ricorsivamente cerca nel sottoalbero di sinistra di u se key[u] > k,
nel sottoalbero di destra di u se key[u] < k, fin quando non trovi un
nodo u con key[u] = k
Tree-Search(x, k) %(x é il puntatore alla radice dell’albero)
if x = NIL oppure k = key[x]
then return (x)
if k < key[x]
then return (Tree-Search(Left[x], k))
else return (Tree-Search(Right[x], k))
Complessitá: O(h) , dove h é l’altezza dell’albero.
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 7/20
Esempio: ricerca di 13
15
6
7
3
2
18
17
20
13
4
9
Per cercare l’elemento 13 seguiamo il cammino 15 −→ 6 −→ 7 −→ 13, a
partire dalla radice
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 8/20
Ricerca del Minimo in un albero binario di ricerca
Tree-Minimum(x)
while Left[x] 6= NIL
x = Left[x]
return (x)
Complessitá: O(h)
• Se un nodo x non ha sottoalbero sinistro, allora poiché ogni nodo nel
sottoalbero di destra di x ha chiave ≥ key[x], ne segue che il minimo del
sottoalbero radicato in x é proprio il nodo x.
• Se un nodo x ha sottoalbero sinistro, allora poiché ogni nodo nel
sottoalbero di destra di x ha chiave ≥ key[x] ed ogni nodo nel sottoalbero
sinistro di x ha chiave ≤ key[x], ne segue che che il minimo del
sottoalbero radicato in x si trova nel sottoalbero radicato nel figlio sinistro
di x.
Analoghe considerazioni varrano per la ricerca del Massimo (che si
troverá o nella radice oppure nel sottoalbero di destra della stessa).
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 9/20
Ricerca del Successore e del Predecessore
• Il successore di un elemento x é definito come quell’elemento y tale che
esso ha la chiave key[y] di valore minimo, tra tutti gli elementi con chiavi
di valore > key[x]
15
6
7
3
2
18
17
20
13
4
9
• Il successore di 15 é 17
• Il successore di 13 é 15
• Il successore di 9 é 13
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 10/20
Ricerca del Successore: distinzione di casi
15
6
7
3
2
18
17
20
13
4
9
• Caso 1: Right(x) 6= NIL
- il successore di x é l’elemento minimo nel sottoalbero destro di x
(ad esempio, il successore di 15 é 17).
• Caso 2: Right(x) = NIL
- sali nell’albero fin quando non trovi un nodo y che é figlio sinistro: il
successore di x é il padre di y.
(ad esempio, il successore di 13 é 15, quello di 9 é 13)
- Se non si puó salire ulteriormente (si é raggiunta la radice) allora
x é il massimo (non ha successore)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 11/20
Ricerca del Successore:
Tree-Successor(x)
if Right[x] 6= NIL
then return (Tree-Minimum(Right[x]))
y = Parent[x]
while y 6= NIL and x = Right[y]
x=y
y = Parent[y]
return (y)
Complessitá: O(h)
Considerazioni perfettamente analoghe varrano per la ricerca del
Predecessore.
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 12/20
Inserzione di un nodo z in un albero binario di ricerca
• Idea: Procedi come se volessi cercare z nell’albero
- se key[x] > key[z] ricorri nel sottoalbero radicato in x = Left[x],
altrimenti nel sottoalbero radicato in x = Right[x].
- quando x = NIL abbiamo trovato la posizione per z
Esempio: inserzione di 7
15
6
18
3
2
8
4
7
17
20
13
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 13/20
La procedura di inserzione
Tree-Insert(T, z)
y = NIL, x = root[T ]
while x 6= NIL
y=x
if key[z] < key[x]
then x = Left[x]
else x = Right[x]
Parent[z] = y
if y = NIL
then root[T ] = z
else if key[z] < key[y]
then Left[y] = z
else Right[y] = z
Esempio: inserzione di 7
15
6
18
3
2
8
4
7
17
13
Complessitá: O(h)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 14/20
20
Cancellazione di un nodo z da un albero binario di ricerca
• Idea:
- Caso 1: z non ha figli
• cancella z facendo puntare il padre di z a NIL invece che a z
Esempio: cancellazione di 13
15
5
3
15
20
12
10
6
=⇒
16
13
18
5
3
16
20
12
23
10
18
6
7
7
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 15/20
23
Cancellazione di un nodo z da un albero binario di ricerca
• Caso 2: z ha un solo figlio y
- cancella z, facendo puntare il padre di z direttamente a y, indi
aggiorna il puntatore al padre di y
Esempio: cancellazione di 16
15
5
3
15
20
12
10
6
=⇒
16
13
18
5
3
20
12
23
10
13
18
6
7
7
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 16/20
23
Cancellazione di un nodo z da un albero binario di ricerca
• Caso 3: z ha due figli
- cancella z, sostituendolo con il nodo a lui piú simile, ovvero
il successore (che per definizione ha al piú un figlio)
Esempio: cancellazione di 5
15
5
3
15
20
12
10
6
5
16
13
18
3
16
20
12
23
10
13
18
6
7
7
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 17/20
23
Cancellazione di un nodo z da un albero binario di ricerca
Esempio: cancellazione di 5
L’albero risultante é
15
6
3
16
20
12
10
13
18
23
7
Complessitá: O(h)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 18/20
Pseudocodice per cancellazione
Tree-Delete(T, z)
if Left[z] =NIL oppure Right[z] =NIL
then y = z
else y = Tree-Successor(z)
if Left[y] 6= NIL
then x = Left[y]
else x = Right[y]
if x 6= NIL
then Parent[x] = Parent[y]
if Parent[y] = NIL
then root[T ] = x
else if y = Left[Parent[y]]
then Left[Parent[y]] = x
else Right[Parent[y]] = x
if y 6= z
then key[z] = key[y]
return (y)
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 19/20
Riassumendo:
La struttura dati Albero Binario di ricerca supporta le operazioni di
S EARCH(S, k), M INIMUM(S), M AXIMUM(S), S UCCESSORE(S, x),
P REDECESSORE(S, x), I NSERT(S, x) e D ELETE(S, x) in tempo O(h),
dove h é l’altezza dell’albero.
Intuitivamente, l’albero sará “abbastanza” bilanciato (h ≈ log n) se si
effettueranno le inserzioni e cancellazioni di elementi scelti a caso
(ma non é detto che questa assunzione valga in pratica).
Nel caso peggiore, l’altezza puó anche essere n, rendendo le
operazioni sull’albero altamente inefficienti (ad es., se si inserissero
gli elementi 1, 2, 3, . . . , n nell’ordine, l’albero binario di ricerca sarebbe
equivalente ad una lista lunga n).
Universitá degli Studi di Salerno – Corso di Introduzione agli Algoritmi e Strutture Dati – Prof. Ugo Vaccaro – Anno Acc. 2014/15 – p. 20/20