Algoritmi e Laboratorio a.a. 2009

annuncio pubblicitario
Sommario
Università di Torino – Facoltà di Scienze MFN
Corso di Studi in Informatica
Curriculum SR (Sistemi e Reti)
• Alberi binari 1-bilanciati in altezza e loro proprietà.
• Alberi AVL = alberi binari di ricerca 1-bilanciati in altezza.
• Operazioni di inserimento e cancellazione in alberi AVL:
• rotazioni di ribilanciamento;
• analisi della complessità.
Algoritmi e Laboratorio a.a. 2009-10
Lezioni
prof. Elio Giovannetti
Lezione 35 – Alberi AVL
versione 21/01/10
Quest' opera è pubblicata sotto una Licenza Creative Commons
Attribution-NonCommercial-ShareAlike 2.5.
21/01/10 21.23
Alberi bilanciati in altezza
• Nota: la denominazione è appropriata, poiché si dimostra
facilmente che gli alberi bilanciati in altezza sono bilanciati,
cioè che al crescere del numero n dei nodi la loro altezza
cresce come Θ(log n) (vedi dimostrazione più avanti).
E. Giovannetti - AlgELab-09-10 - Lez.35
3
Alberi 1-bilanciati col minimo numero di nodi.
Base: Gli alberi 1-bilanciati di altezza 0 o 1 di dimensione
minima, cioè aventi il numero minimo di nodi sono:
h=0
n0 = 1
h=1
n1 = 2
oppure
Passo: L'albero 1-bilanciato di altezza h di dimensione minima
è un albero
lb
d
della
ll f
forma sottostante
tt t t o sua speculare:
l
nh = 1 + nh-1 + nh-2
h
h-1
T1
T2
2
Alberi bilanciati in altezza.
Definizione non induttiva
• albero binario k-bilanciato (in altezza): in ogni nodo l'altezza
del figlio sinistro e quella del figlio destro differiscono al
più di k;
in particolare:
• albero binario 1-bilanciato (in altezza): in ogni nodo l'altezza
del figlio sinistro e quella del figlio destro differiscono al
più di 1;
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
h-2
dove T1 e T2 sono alberi 1-bilanciati di dimensione minima
di
altezze
rispettivamente
e h-2.- Lez.35
21/01/10
21.23
E. Giovannetti h-1
- AlgELab-09-10
5
Definizione induttiva, equivalente alla precedente
• Un albero vuoto (o di un solo elemento) è k-bilanciato.
• Un albero (T1 el T2) è k-bilanciato se:
• T1 è k-bilanciato;
• T2 è k-bilanciato;
• le altezze di T1 e T2 differiscono al più di k.
e ovviamente, in particolare:
• Un albero vuoto (o di un solo elemento) è 1-bilanciato.
• Un albero (T1 el T2) è 1-bilanciato se:
• T1 è 1-bilanciato;
• T2 è 1-bilanciato;
• le altezze di T1 e T2 differiscono al più di 1.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
4
Alberi 1-bilanciati col minimo numero di nodi.
Allora il num. di nodi nh di un albero 1-bilanciato di altezza h
di dimensione minima soddisfa alle equazioni di ricorrenza:
n0 = 1
n1 = 2
nh = nh-1 + nh-2 + 1 per k ≥ 2
Risolvendo per un minorante:
n2 = n0 + n1 + 1 > n0 + n0 = 2n0 = 2
n4 = n2 + n3 + 1 > n2 + n2 = 2n2 > 2⋅2 = 22
n6 = n4 + n5 + 1 > n4 + n4 = 2n4 > 2⋅22 = 23
...
n2i > 2i, d'altra parte si ha n2i+1 > 2i, quindi nh > 2⎣h/2⎦
Dunque
n = Ω((√2)h)
e anche
log nh > ⎣h/2⎦ > h/2 – 1
h = O(log n), quindi h = Θ(log n)
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
6
1
Gli alberi 1-bilanciati sono bilanciati.
Alberi di Fibonacci
(= alberi 1-bilanciati di dimensione minima)
Dunque il numero di nodi minimo di un albero 1-bilanciato
cresce esponenzialmente rispetto all'altezza dell'albero;
quindi anche il num. di nodi di un albero 1-bilanciato qualsiasi
cresce esponenzialmente rispetto all'altezza, e l'altezza è
quindi logaritmica nel numero dei nodi.
Per gli alberi 1-bilanciati (in altezza):
h = Θ(log n)
Con ragionamento analogo si vede che ciò vale più in generale
per gli alberi k-bilanciati, con k fissato.
h=0
h=1
h=2
h=3
Gli alberi 1-bilanciati o k-bilanciati sono dunque bilanciati !
h=4
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
7
21/01/10 21.23
Alberi AVL (dai nomi dei due inventori)
AV vive attualmente in Israele, L è morto a Mosca nel 1997.
alberi AVL: alberi di ricerca binari
che vengono mantenuti 1-bilanciati.
Come ?
E. Giovannetti - AlgELab-09-10 - Lez.35
9
Автобиография (Autobiografia)
Первая научная работа была сделана мной в 1944 г., когда я был
студентом 4-го курса.
...
Раньше, чем на Западе, мы разработали метод организации
программ, которые могут использовать себя, как подпрограмму и
как подпрограммы своих подпрограмм. Вместо системы списков,
использующей
й язык LISP,
LISP мы разработали
б
удобные
б
стандарты
программирования списков (это же сделал Д. Кнут, но после
нас).
Наконец, следует отметить конструкцию текущей справочной,
разработанную E.M. Ландисом и мною, для которой количество
элементарных действий, как для включения нового элемента
информации, так и для исключения старого пропорционально
логарифму объема справочной.
...
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
E. Giovannetti - AlgELab-09-10 - Lez.35
10
Alberi AVL
E. M. Landis
Evgenii Mikhailovich Landis was born on October 6, 1921, in Kharkov. Four years later, the
family moved to Moscow. His interest to mathematics arose early, when he was in high
school; so it was natural to him to apply to The Department of Mathematics and Mechanics of
the Moscow State University. He was admitted there in 1939, but he was not able to study for
long time: he was drafted, and in the six years that followed he had to fight in two wars; he
was wounded, he was shell-shocked, he got severe frost-bites, many times he was on the edge.
In 1945, when the war was over, Evgenii Mikhailovich was discharged, and he re-enrolled in
the MSU. ... By the time he graduated from the Moscow State University, he had had 5
published papers. However, because of the official antisemitic policies that were in place at
that time, he was denied the admission to the graduate school. He started working as a school
teacher. Finally, Landis got his PhD in 1953, and, in 1956, he wrote his Doctor of Science
di
dissertation
i "Some
"S
properties
i off the
h solutions
l i
off Elliptic
Elli i Equations."
E
i
" This
Thi dissertation
di
i was a
starting point for his interest in qualitative theory of PDEs. It is impossible to survey all his
work in his direction. ...
However, he worked in other fields as well. In 1962, in collaboration with Adel'son-Velsky,
he published a paper "An algorithm for the organization of information." According to their
algorithm, for a data structure that contains entries, the number of operation that is required
for adding a new entry, and the number of operation that is required for retrieving an entry are
proportional to log. This algorithm is called the AVL algorithm; now it is a part of any course
in computer science, and it is used in many software products. ...
He loved music; one could often see him in the Moscow Conservatory. He liked to draw, his
paintings were part of an exhibition in the MSU Faculty Club. He lived in a difficult place in a
difficult time and was making the life around him better.
21/01/10 21.23
8
G. M. Adelson-Velskii
Inventati nel 1962 dai due (non tre !) matematici sovietici
Adelson-Velskii (Адельсон-Вельский) e Landis (Ландис)
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
11
Le operazioni di inserimento ed eliminazione di un elemento
effettuano ogni volta, se necessario, un ribilanciamento,
per mezzo di opportune trasformazioni dell'albero, dette
(un po' fantasiosamente) rotazioni, che lo rendono bilanciato
pur mantenendone la proprietà di essere un albero di ricerca.
Esempio:
ribilancia con
una "rotazione"
" t i
"
inserisci 3
7
7
5
5
5
3
7
3
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
12
2
Alberi AVL
Definizioni
Un altro esempio:
• sbilanciamento di un nodo (o di un albero) = differenza fra
le altezze del sottoalbero di sinistra e di quello di destra;
albero T Æ
ribilancia con
una "rotazione"
" t i
"
inserisci 6
7
5
7
5
hS
6
5
D
S
7
E. Giovannetti - AlgELab-09-10 - Lez.35
hD
•sbil > 0: l'albero "pende" a sinistra;
•sbil = 0: il nodo è "perfettamente bilanciato";
•sbil < 0: l'albero "pende" a destra;
6
21/01/10 21.23
sbil(v) = sbil(T) = hS - hD
v
13
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Sbilanciamento e alberi 1-bilanciati.
14
Nota terminologica.
Nota: è indifferente considerare lo sbilanciamento come
• proprietà di un albero, oppure
• proprietà del nodo radice di quell'albero.
Nota Bene:
sbil(T) = 0 non implica che T sia 1-bilanciato;
o, considerando lo sbilanciamento come proprietà dei nodi:
sbil(v) = 0 non implica che ll'albero
albero di radice v sia 1-bilanciato
1 bilanciato
• Considerando lo sbilanciamento come proprietà dei nodi, se
un nodo ha sbilanciamento < 2 in valore assoluto, si dice
talvolta per brevità che il nodo è 1-bilanciato.
• Analogamente un nodo il cui sbilanciamento sia > 2 in valore
assoluto viene talvolta detto per brevità nodo sbilanciato.
• Un albero binario 1-bilanciato è q
quindi un albero binario in
cui tutti i nodi sono 1-bilanciati.
Un albero T è 1-bilanciato (in altezza) se e solo se
per ogni sottoalbero T' di T si ha |sbil(T')| ≤ 1
(dove fra i sottoalberi di un albero T vi è anche T stesso),
o, considerando lo sbil. come proprietà dei nodi:
in ogni nodo v di T si ha |sbil(v)| ≤ 1.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
15
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Ribilanciamento.
Sbilanciamento a sinistra.
Se T è un albero binario di ricerca 1-bilanciato, l'inserimento
o l'eliminazione di un nodo può causare in qualche nodo di T
uno sbilanciamento di al massimo ± 2.
Sia T un albero binario di ricerca di radice b con sbil(b) = +2,
e con |sbil(u)| ≤ 1 per ogni altro nodo u.
cioè per tutti gli altri nodi v dell'albero sia |sbil(v)| ≤ 1.
• Nota: T è un albero 2-bilanciato i cui sottoalberi propri
sono tutti 1-bilanciati.
• Come si trasforma un tale albero binario di ricerca T
in un albero binario di ricerca 1-bilanciato ?
E. Giovannetti - AlgELab-09-10 - Lez.35
17
sbil(b) = +2
b
• Consideriamo allora un albero binario di ricerca T in cui:
• sbilanciamento della radice = ± 2;
• i sottoalberi sinistro e destro siano 11-bilanciati,
bilanciati, e quindi
tutti i sottoalberi siano 1-bilanciati,
21/01/10 21.23
16
h+2
S
D
h
2
• L'albero D può anche essere vuoto (se D è vuoto (h = -1),
allora S ha due livelli, cioè altezza 1), ma
• l'albero S sicuramente non lo è, quindi ha un nodo radice a
e due figli SS e SD. T ha quindi una delle forme seguenti:
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
18
3
Sbilanciamento a sinistra: i due casi.
caso SS (sottocasi 1 e 2)
b
h
D
1
1
2
b
SS
D
1
SD
h
h+2
h
D
SD
2
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
h+2
19
21/01/10 21.23
b sbil = +2
a
h
D
SD
1
1
h+2
21/01/10 21.23
21
21/01/10 21.23
Caso SS (sottocaso 1): rotazione SS.
2
E. Giovannetti - AlgELab-09-10 - Lez.35
22
Caso SS (sottocaso 1): rotazione SS.
sbil = 0
a
sbil = 0
b
b
h+1
D
h
h+1
h+1
SS
1
SD
D
h
h+1
1
SS a (SD b D)
Abbiamo applicato una specie di proprietà associativa;
• SS ha diminuito di 1 l'annidamento, quindi è salito di 1 liv.;
• D ha aumentato di 1 l'annidamento, quindi è sceso di 1 liv.;
• SD ha lo stesso annidamento, quindi lo stesso livello.
21/01/10 21.23
1
1
SS a (SD b D)
E. Giovannetti - AlgELab-09-10 - Lez.35
SD
h
D
SD
SS
2
(SS a SD) b D
SS
20
Caso SS (sottocaso 1): animazione rotazione SS.
a
a
2
E. Giovannetti - AlgELab-09-10 - Lez.35
b sbil = +2
SS
1
1
Sfruttiamo la rappresentazione lineare infissa dell'albero:
(SS a SD) b D (omettendo le parentesi più esterne)
• bisogna trasformarlo in modo da far salire SS e scendere D
mantenendo la stessa sequenza inorder;
• a tal fine basta parentesizzare diversamente, giacché il
livello (della radice) di un sottoalbero in un albero è dato
dal numero di parentesi in cui è annidato.
Caso SS (sottocaso 1): animazione rotazione SS.
h+2
h
D
SD
SS
2
Nota: nei disegni il nome del caso
coincide con il nome del sottoalbero
che "causa" lo sbilanciamento.
a
SS
h+2
Nota Bene:
SD e D possono anche essere vuoti;
SS è sicuramente non vuoto.
a
a
SD
SS
b
b
a
h+2
Caso SS (sottocaso 1)
caso SD
E. Giovannetti - AlgELab-09-10 - Lez.35
23
SS a (SD b D)
Abbiamo applicato una specie di proprietà associativa;
• SS ha diminuito di 1 l'annidamento, quindi è salito di 1 liv.;
• D ha aumentato di 1 l'annidamento, quindi è sceso di 1 liv.;
• SD ha lo stesso annidamento, quindi livello, di prima.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
24
4
Riassumendo: rotazione SS (nel sottocaso 1).
b sbil = +2
Caso SS (sottocaso 2)
sbil = 0
a
a
b sbil = +2
a
b
h+2
SS
h
D
SD
1
1
SS
2
SD
D
h+1
h
E. Giovannetti - AlgELab-09-10 - Lez.35
h
D
SS
25
b
h+2
1
(SS a SD) b D
SS a (SD b D)
Come si vede,
• lo sbilanciamento della radice passa da 2 a 0;
• l'altezza dell'albero diminuisce di 1 (passa da h+3 ad h+2);
• lo sbilanciamento del sottoalbero destro (SD b D) è 0.
21/01/10 21.23
SD
2
21/01/10 21.23
D
X
SD
h
h+2
2
• Lo sbilanciamento del caso SS2 si può creare solo in seguito
all'eliminazione di un nodo che faccia diminuire l'altezza di
D da h+1 ad h, ma non in seguito a un inserimento.
• Infatti l'inserimento di un nodo in un albero 1-bilanciato di
radice b non può far aumentare l'altezza di entrambi i
sottoalberi SS e SD (e se uno dei due avesse già altezza
h+2 lo sbilanciamento si sarebbe già realizzato prima).
E. Giovannetti - AlgELab-09-10 - Lez.35
27
Caso SD: verso la soluzione
1
D
SD
D
1
SD
2
21/01/10 21.23
SD
2
D
h+2
h
1
E. Giovannetti - AlgELab-09-10 - Lez.35
h+2
2
E. Giovannetti - AlgELab-09-10 - Lez.35
SS
(SS a SD) c D
SS a (SD c D)
La rotazione usata nel caso SS non è una soluzione !
Essa infatti fa scendere D eliminando così il dislivello di 2
fra SD e D, ma contemporaneamente fa salire SS creando
così un nuovo dislivello di 2 fra SS e SD ! Il risultato è che il
nodo radice a è ancora sbilanciato !
h
28
29
c
b
SS
1
• Evidentemente bisogna riuscire a "sollevare" SD senza far
salire SS, ricordando che SD deve stare inorder fra a e c.
Osserviamo che:
• SS e D possono anche essere nulli, ma SD sicuramente non
lo è. L'albero SD contiene quindi almeno un nodo radice non
nullo, con due sottoalberi eventualmente nulli.
21/01/10 21.23
SS
c
h
Caso SD sottocaso 1: T1 e T2 hanno altezze diverse.
a
SS
sbil = -1
a
Nota: nel disegno T2 può
anche essere vuoto.
a
c
h
1
26
a
h+2
h+2
h
Caso SD
a
h+2
SD
c
h+1
D
E. Giovannetti - AlgELab-09-10 - Lez.35
b sbil = +2
21/01/10 21.23
SS
(SS a SD) b D
SS a (SD b D)
Anche in questo caso la rotazione SS risolve il problema:
• lo sbilanciamento della radice passa da 2 a -1;
• l'altezza dell'albero rimane invariata;
• lo sbilanciamento del sottoalbero destro (SD b D) è 1.
Osservazione importante
SS
sbil = -1
a
h
T2
T1 h
1
D
h
2
(SS a (T1 b T2)) c D
Risistemiamo le parentesi mantenendo la sequenza inorder, in
modo da diminuire l'annidamento sia di T1 che di T2, ma non
quello di SS.
Nota: Il sottocaso in cui i ruoli di T1 e T2 sono invertiti si
tratta quindi con la stessa trasformazione.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
30
5
Caso SD (sottocaso 1): rotazione SD.
Caso SD (sottocaso 1): rotazione SD.
c
b
a
a
b
h+2
h
SS
1
h
D
T2
T1 h
1
h+1
SS
2
Nota: Il sottocaso in cui i ruoli di T1 e T2 sono invertiti si
tratta quindi con la stessa trasformazione.
E. Giovannetti - AlgELab-09-10 - Lez.35
c
31
21/01/10 21.23
h+2
SS
h
T1
1
h
h+1
E. Giovannetti - AlgELab-09-10 - Lez.35
32
Caso SD (sottocaso 2).
D
b
a
a
b
SS
2
T2
D
1
c
Nota: T1 e T2 possono
essere entrambi vuoti
(nel qual caso SS e D
sono anch'essi vuoti).
a
h
T1
h
(SS a T1) b (T2 c D)
• I sottoalberi T1 e T2 sono stati sollevati, D si è abbassato,
SS è rimasto allo stesso livello. L'albero è 1-bilanciato.
• L'altezza dell'albero è diminuita di 1, da h+3 ad h+2.
• Nota: Si vede facilmente che la trasformazione funziona
anche se le altezze di T1 e T2 sono scambiate.
Caso SD (sottocaso 2).
b
T2
1
(SS a T1) b (T2 c D)
Risistemiamo le parentesi mantenendo la sequenza inorder, in
modo da diminuire l'annidamento sia di T1 che di T2, ma non
quello di SS.
21/01/10 21.23
h
c
1
h
T1
h
h
T2
D
SS
2
h
c
T1
T2
1
D
h
1
A h iin questo
Anche
t caso la
l rotazione
t i
SD risolve
i l in
i problema.
bl
Nota:
A differenza del sottocaso 2 del caso SS, nel sottocaso 2
del caso SD l'altezza dell'albero diminuisce di 1 come nei
casi SS, DD, e SD 1.
b
a
h+1
h
SS
c
T1
T2
D
h
h+1
1
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
33
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Osservazione.
Sbilanciamento a destra.
c
u
a
h+2
b
SS
1
h
T1
h
h
T2
2
D
h
X
• Lo sbilanciamento del caso SD2 si può creare sia in seguito
all'eliminazione di un nodo che faccia diminuire l'altezza di
D da h ad h-1, che in seguito a un inserimento di b con T1 e
T2 entrambi vuoti.
c
c
a
inserisci b
a
b
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
34
35
sbil(u) = -2
h+2
S
2
D
• È ovviamente speculare di quello a sinistra, quindi si scinde
in due casi DD e DS che si risolvono con rotazioni anch'esse
speculari rispettivamente di SS e DS.
• Ad esempio, la rotazione DD sarà:
S a (DS b DD) Æ (S a DS) b DD
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
36
6
Osservazione
Le rotazioni "miste" come rotazioni doppie.
Le rotazioni SD e DS possono essere ottenute per mezzo
delle altre due. Esempio:
rotazione SD
(SS a (T1 c T2)) b D
(SS a T1) c (T2 b D)
Le rotazioni SS e DD sono l'una l'inversa dell'altra:
(T1 a T2) b T3
21/01/10 21.23
SS
Æ
Å
DD
T1 a (T2 b T3)
E. Giovannetti - AlgELab-09-10 - Lez.35
37
Le rotazioni "miste" come rotazioni doppie.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
38
Le rotazioni "miste" come rotazioni doppie.
Le rotazioni SD e DS possono essere ottenute per mezzo
delle altre due. Esempio:
Le rotazioni SD e DS possono essere ottenute per mezzo
delle altre due. Esempio:
(SS a (T1 c T2)) b D
(SS a (T1 c T2)) b D
rotazione DD
sul sinistro
(SS a T1) c (T2 b D)
rotazione DD
sul sinistro
((SS a T1) c T2) b D
SSaT1 c (T2 b D)
(SSaT1 c T2) b D
rotazione SS
consideriamo (SS a T1) come un unico sottoalbero SSaT1
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
39
Le rotazioni "miste" come rotazioni doppie.
rotazione DD
sul sinistro
SSaT1 c (T2 b D)
(SSaT1 c T2) b D
rotazione SS
E. Giovannetti - AlgELab-09-10 - Lez.35
40
Le rotazioni SD e DS possono essere ottenute per mezzo
delle altre due. Esempio:
rotazione SD
(SS a (T1 c T2)) b D
(SS a T1) c (T2 b D)
rotazione DD
sul sinistro
consideriamo (SS a T1) come un unico sottoalbero SSaT1
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Le rotazioni "miste" come rotazioni doppie.
Le rotazioni SD e DS possono essere ottenute per mezzo
delle altre due. Esempio:
(SS a (T1 c T2)) b D
21/01/10 21.23
41
((SS a T1) c T2) b D
rotazione SS
Per modificare un sottoalbero t tramite la rotazione SD
basta quindi eseguire il seguente banale algoritmo:
void sd(Node T) {
dd(T.left);
ss(T)
}
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
42
7
Terminologia
Riassumendo:
• Le rotazioni SS e DD vengono dette rotazioni semplici.
• Le rotazioni SD e DS vengono dette rotazioni doppie,
proprio perché ognuna di esse si può ottenere per mezzo di
due rotazioni semplici.
• Per numero di rotazioni eseguite da un'operazione sugli
alberi AVL si intende il numero di ribilanciamenti eseguiti:
quindi una rotazione doppia conta per una.
• La radice del (sotto-)albero cui si applica una rotazione
viene talvolta impropriamente detto perno della rotazione.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
43
Anticipazione di conseguenza importante
E. Giovannetti - AlgELab-09-10 - Lez.35
45
Inserimento: algoritmo ricorsivo astratto.
void inser(Elemento el, AVLTree t) {
if(t è vuoto)
modifica t creando un nodo-radice contenente el;
else if(chiaveDi(el) == chiaveDi(t.element))
sostituisci t.element con el;
else {
if(chiaveDi(el) < chiaveDi(t.element))
inser(el, t.sinist);
else inser(el, t.destr);
if(|sbil(t)| > 1) ribilancia t con l'opportuna rotazione;
}
}
Domanda: il ribilanciamento di un sottoalbero può richiedere
il successivo ribilanciamento di un altro (sotto-)albero ?
La risposta nelle prossime slides.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
• Le rotazioni nei sottocasi
SS2
e
DD2
sono le uniche che lasciano invariata l'altezza del sottoalbero.
• Ma l'inserimento di un nuovo elemento non può produrre
i sottocasi di sbilanciamento SS2 e DD2.
• Quindi una rotazione dovuta a inserimento decrementa
sempre di 1 l'altezza dell'albero "ruotato".
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
44
Le operazioni di inserimento e cancellazione.
• Come vedremo, un inserimento che sbilanci un albero ne
aumenta sempre di 1 l’altezza.
• Ma, come abbiamo appena visto, la susseguente rotazione
dovuta a inserimento decrementa sempre di 1 l'altezza
dell'albero "ruotato".
• Alla fine, dopo l’inserimento e la rotazione, l’albero ha
quindi la stessa altezza di prima dell’inserimento.
dell inserimento.
21/01/10 21.23
• Le rotazioni nei casi SD, DS e nei sottocasi SS1, DD1
fanno diminuire di 1 l'altezza del sottoalbero cui sono
applicate.
47
Per inserire o cancellare un elemento in un albero AVL:
• si inserisce o si elimina l'elemento come in un albero binario
di ricerca ordinario, creando o eliminando un nodo;
• se in seguito a ciò qualche sottoalbero è diventato non più
1-bilanciato, lo si ribilancia tramite l'opportuna rotazione;
• poiché le rotazioni funzionano sulla base dell'ipotesi che i
due sottoalberi figli del nodo perno siano 1-bilanciati (e che
quindi tutti i loro nodi abbiano sbil < 2 in valore assoluto),
l'albero che bisogna ribilanciare è il più piccolo albero che
si è sbilanciato: ciò è automaticamente garantito dalla
definizione ricorsiva dell'algoritmo.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
46
Inserimento con sbilanciamento/ribilanciamento:
una proprietà importante.
• L'incremento di altezza di un sottoalbero T può portare lo
sbilanciamento del genitore p di T da 1 a 2 o da –1 a –2.
• Se ciò accade, anche l'altezza dell'albero di radice p
aumenta sicuramente di 1.
• Lo sbilanciamento provocato da un inserimento può essere
solo
l del
d l genere SS1,
SS1 DD1,
DD1 SD
SD, o DS.
DS
• Ma in tal caso la rotazione di ribilanciamento fa diminuire
di 1 l'altezza dell'albero di radice p (vedi slide prec.).
• Quindi, dopo il ribilanciamento, l'albero di radice p ha la
stessa altezza di prima dell'inserimento (l'inserimento
sbilanciante l'ha fatta aumentare di 1, la rotazione l'ha
fatta diminuire di 1).
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
48
8
Inserimento con sbilanciamento/ribilanciamento.
Vale dunque il seguente importante
Lemma. L'inserimento di un nodo in un (sotto-)albero T, se
provoca una rotazione avente per perno la radice di T, non
modifica l'altezza di T rispetto a prima dell'inserimento.
Conseguenza:
L'inserimento di un nodo in un (sotto-)albero T, se provoca lo
sbilanciamento di T ma di nessun suo sottoalbero,
sottoalbero e quindi
una rotazione di T, non ne modifica l'altezza; dunque non può
causare lo sbilanciamento di nessun altro (sotto-)albero che
contenga T. Quindi:
Teorema: Un inserimento in albero AVL richiede al massimo
una rotazione (semplice o doppia).
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
49
Esempio (caso SS)
albero T Æ
SS
h
51
Altezza e operazioni sull'albero
1
E. Giovannetti - AlgELab-09-10 - Lez.35
D
2
b
h+2
SS
1
SD
h
D
• inizialmente l'altezza di SS, SD, D è h, l'altezza di T è h+2;
• si inserisce un nodo in SS:
•l'altezza di SS diventa h+1, l'altezza di T diventa h+3;
•ma T si sbilancia;
•allora si fa una rotazione SS per ribilanciare; ma essa fa
di nuovo diminuire di 1 l'altezza di T, riportandola ad h+2.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
50
typedef struct Nodo* AVLTree;
(nel file .h)
typedef struct Nodo {
Studente elem;
AVLTree sx;
AVLTree dx;
int h; // altezza
} Nodo;
(nel file .c)
int altezza(AVLTree t) {
se t non è vuoto restituisce il valore del campo h,
se t è vuoto restituisce –1 (oppure 0, a seconda di come si
decide di contare le altezze)
}
int sbil(AVLTree t) {
...
}
21/01/10 21.23
// sbilanciamento
E. Giovannetti - AlgELab-09-10 - Lez.35
52
Altezza e operazioni: una proprietà ovvia.
• L'inserimento o cancellazione di un nodo in un albero
può modificarne l'altezza;
• a sua volta la variazione di altezza di un sottoalbero-figlio
può modificare l'altezza del nodo genitore (l'altezza di un
albero è uguale a 1 + l'altezza del più alto dei suoi due figli);
• pertanto in ciascun (sotto-)albero T, dopo l'inserimento o
cancellazione in uno dei sottoalberi-figli,
sottoalberi figli, bisogna
bisogna:
• controllare se l'altezza di tale figlio è variata;
• se è variata:
• controllare se tale variazione provoca una variazione
dell'altezza dell'albero T, e se si, aggiornare il campoaltezza (del nodo radice di T);
• controllare se ciò ha prodotto uno sbilanciamento.
21/01/10 21.23
SD
h
Esempio in C (italo-inglese)
• Affinché il tempo necessario per l'inserimento si mantenga
proporzionale alla lunghezza del cammino dalla radice
dell'albero fino al punto di inserimento – e quindi O(log n) –
bisogna che:
• sbil(T) possa essere (ri-)calcolato in tempo costante,
senza visitare tutto il sottoalbero T.
• Ma Nota Bene:
• lo sbil. di un nodo non è funzione degli sbil. dei figli;
• l'altezza è invece funzione delle altezze dei figli.
• Ogni nodo deve quindi contenere il valore dell'altezza del
sottoalbero di cui quel nodo è radice: la struttura-nodo
deve quindi contenere un campo supplementare altezza.
• Naturalmente ogni operazione di modifica dell'albero deve
aggiornare correttamente tale campo.
E. Giovannetti - AlgELab-09-10 - Lez.35
a
a
Struttura-dati per la realizzazione.
21/01/10 21.23
b
53
• L'inserimento o cancellazione di un nodo può causare una
variazione del valore del campo-altezza solo nei nodi posti
sul cammino dalla radice al nodo creato.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
54
9
Inserimento: algoritmo ricorsivo.
Qualche suggerimento per l'implementazione
void inser(Elemento el, AVLTree t) {
if(t è vuoto)
modifica t
creando un nodo-radice contenente el, con altezza = 0 ;
else if(chiaveDi(el) == chiaveDi(t.element))
sostituisci t.element con el;
else {
if(chiaveDi(el)
f( h
D ( l) < chiaveDi(t.element))
h
D( l
))
inser(el, t.sinist);
else inser(el, t.destr);
}
}
if(|altezza(t.sinist) – altezza(t.destr)| < 2)
t.altezza = 1 + max(altezza(t.sinist), altezza(t.destr));
else individua la rotazione opportuna ed eseguila;
Nota: Le procedure di rotazione devono, al loro interno,
aggiornare correttamente i campi-altezza dei nodi coinvolti.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
55
Conviene strutturare il codice con procedure ausiliarie, es.:
void aggiornaAltezza(Tree t) {
... se t non è vuoto ecc.
}
void ribilanciaOppureAggiornaAltezza(Tree* pt) {
assumendo che nei nodi dei sottoalberi-figli le altezze
siano tutte corrette,, calcola lo sbilanciamento di *pt
p
e, se necessario, effettua l'opportuna rotazione;
altrimenti aggiorna semplicemente l'altezza di *pt.
}
void ss( ... ) {
...
}
eccetera.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
56
Correttezza dell'algoritmo ricorsivo di inserimento
Correttezza dell'algoritmo ricorsivo di inserimento
Dimostrazione (facile) di correttezza
per induzione strutturale sull'albero.
• Passo: Inserimento in un albero T non vuoto, di radice r.
Ip. Ind.: L'inserimento in T.sinist o T.destr è corretto.
Tesi Ind.: L'inserimento in T è corretto.
Dimostrazione del passo.
Dopo l'inserimento in T.sinist o T.destr:
• per ip. ind. i campi altezza dei (nodi-radice di) T.sinist e
T.destr contengono
g
i valori corretti;; lo sbil. della radice r
di T si ottiene quindi con una semplice differenza;
• per ip. ind. i due sottoalberi T.sinist o T.destr sono ancora
1-bilanciati, cioè tutti i nodi di T, tranne al più la radice r,
hanno |sbil| < 2;
• allora se |sbil| di r risulta > 1, T è un albero in cui solo la
radice è sbilanciata: che è proprio la situazione che può
essere risolta da un'opportuna rotazione;
• altrimenti T è già 1-bilanciato, basta aggiornare il campo
altezza
della radice.
21/01/10
21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
58
• Base: L'inserimento di un elemento nell'albero vuoto è
corretto p
perché crea un albero costituto da un solo nodo,
quindi 1-bilanciato, con il campo-altezza correttamente
impostato a 0.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
57
Correttezza dell'algoritmo ricorsivo di inserimento
• Allora le tre ultime righe della descrizione dell'algoritmo,
le quali appunto:
• aggiornano il campo-altezza della radice, oppure
• effettuano una rotazione con perno la radice (che ne
imposta
p
anche correttamente l'altezza))
realizzano un inserimento corretto, perché:
• l'albero T modificato è ancora di ricerca e 1-bilanciato;
• i campi-altezza contengono i valori corretti.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
59
Inserimento: esempio.
• Si inserisce l'elemento creando un nuovo nodo al posto di un
nodo nullo. L'altezza del sottoalbero che prima era nullo
passa quindi da –1 a 0.
Indicando con h(v) l'altezza
inserisci 6: 10
dell'albero di radice v, si ha:
h(sx di 7), cioè h(6) : -1 Æ 0;
h(7): 0 Æ 1
4
15
h(4): 1 Æ 2;
h(10): 3 Æ 3
Sbilanciamento dei nodi:
3
12
7
18
sbil(7): 0 Æ 1;
sbil(4): 0 Æ -1;
sbil(10): -1 Æ 0.
6
19
L'albero è rimasto 1-bilanciato, non occorre ribilanciare,
ma solo aggiornare E.i Giovannetti
campi-altezza.
- AlgELab-09-10 - Lez.35
60
21/01/10 21.23
10
Inserimento: un altro esempio.
Continuazione esempio.
inserisci 6:
10
4
15
3
7
6
Variazioni delle altezze:
h(6): -1 Æ 0;
h(7): 0 Æ 1
h(4):
( ) 1 Æ 2;;
h(10): 2 Æ 3
...
Variazioni degli sbil.:
...
sbil(10): 1 Æ 2
• Si crea uno sbilanciamento, occorre una rotazione SD di
perno il nodo 10.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
61
10
4
15
3
7
6
((•3•) 4 ((•6•) 7 •)) 10 (•15•)
( SS 4 ( T1 7 T2)) 10 D
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Continuazione esempio.
rotazione SD
Continuazione esempio
10
4
rotazione SD
7
4
15
3
3
7
10
6
15
6
((•3•) 4 (•6•)) 7 (• 10 (•15•))
( SS 4 T1 ) 7 (T2 10 D )
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
63
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
64
Inserimento: algoritmo iterativo.
• Si effettua l'inserimento eseguendo l'algoritmo iterativo
per alberi di ricerca ordinari (vedi slides lez 29, n.36).
• Poi si risale nel cammino percorso dalla radice al nodo,
aggiornando i valori dei campi-altezza, e ricalcolandone gli
sbilanciamenti.
• Se si incontra un nodo il cui sbilanciamento diventa +2
2 o –2
2,
si effettua l'opportuna rotazione e si termina (infatti il
Teorema di slide 49 garantisce che non occorre fare altro).
• Anche se si incontra un nodo in cui l'aggiornamento non
cambia l'altezza, si può ovviamente terminare.
Nota: Nell’algoritmo iterativo è conveniente usare nodi con
riferimento al genitore !
E. Giovannetti - AlgELab-09-10 - Lez.35
L'altezza dell'albero di
radice 7 è la stessa di
prima dell'inserimento.
Quindi il genitore e gli
antenati del perno non
vengono sbilanciati.
((•3•) 4 (•6•)) 7 (• 10 (•15•))
Inserimento: algoritmo iterativo.
21/01/10 21.23
62
65
void inser(Elemento el, AVLTree t) {
while(t non è vuoto) {
if(chiaveDi(el) < chiaveDi(t.element)) t = t.sinist;
else if(chiaveDi(el) > chiaveDi(t.element)) t = t.destr;
else { sostituisci t.element con el; return; }
}
modifica t creando un nodo contenente el con altezza = 0;
p = genitore di t;
while(p non è nullo) {
if(sbil(p) uguale a -2 o +2) {
esegui l'opportuna rotazione; return;
} else {
aggiorna l'altezza di p;
if(l'altezza di p non è cambiata) return;
}
p = genitore di p;
}
} 21/01/10 21.23
Ma attenzione:
vedi slide successiva !
E. Giovannetti - AlgELab-09-10 - Lez.35
66
11
Inserimento: algoritmo iterativo.
Eliminazione del minimo e cancellazione di elemento
Attenzione !
Come nel caso degli alberi di ricerca ordinari l'algoritmo
descritto nella slide precedente è direttamente traducibile
in una procedura C, ma non in un metodo Java o C#.
Per l'implementazione in Java occorre adottare una versione
analoga a quella ad es. di slide lez29 n.70.
• L'eliminazione ordinaria di un nodo in un albero può causare
una diminuzione ma non un aumento dell'altezza dell'albero.
• Il decremento di altezza di un sottoalbero T può portare lo
sbilanciamento del genitore p di T da 1 a 2 o da –1 a –2.
• Se ciò accade, l'altezza dell'albero di radice p sicuramente
rimane invariata (perché si "accorcia" il sottoalbero-figlio
che è già meno alto).
• In tal
t l caso
c s la
l successiva
succ ssiv rotazione
r t zi n di ribilanciamento
ribil nci m nt può
far diminuire di 1 l'altezza dell'albero di radice p (nei casi
SD, DS, SS1, DD1). Quindi:
• Dopo il ribilanciamento, l'altezza dell'albero di radice p può
risultare decrementata di 1 rispetto all'altezza di prima
della cancellazione del nodo.
• Ciò può provocare uno sbilanciamento in un nodo antenato,
quindi una rotazione che può diminuire l'altezza, e così via.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
67
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Eliminazione del minimo e cancellazione di elemento
68
Esempio
• Nel caso peggiore si possono quindi avere sbilanciamenti a
cascata, uno per ogni nodo del cammino dalla radice al nodo
eliminato.
• Nel caso peggiore si hanno quindi Θ(log n) rotazioni; la
complessità dell'operazione è dunque ancora O(log n).
• Le versioni ricorsiva e iterativa dell'algoritmo astratto
sono, in base alle osservazioni precedenti, abbastanza
ovvie, e vengono lasciate per esercizio.
Cancelliamo il nodo 1:
• il sottoalbero di radice 2 diminuisce di uno l'altezza
(ma non si sbilancia);
• per effetto di ciò il sottoalbero di radice 3 non varia la
propria altezza ma il suo sbilanciamento diventa -2.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
69
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
Esempio
70
Esempio (continua).
• Si esegue una rotazione DD: l'altezza del sottoalbero
ruotato diminuisce di 1.
8
13
5
3
2
11
6
4
7
(•2•) 3 ( (•4•) 5 (• 6 (•7•)) )
E. Giovannetti - AlgELab-09-10 - Lez.35
12
10
((•2•) 3 (•4•)) 5 (• 6 (•7•))
21/01/10 21.23
9
16
((•2•) 3 (•4•)) 5 (• 6 (•7•))
71
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
19
14
15
17
20
18
72
12
Esempio (continua).
Esempio (continua).
Lo sbilanciamento del nodo 8 diventa –2.
8
h = 5
13
13
5
3
2
7
nuova rotazione DD,
con perno 8
9
16
12
19
T1 8 (T2 13 T3)
15
16
5
14
10
h = 4
8
11
6
4
21/01/10 21.23
• L'altezza del sottoalbero ruotato è diminuita di 1.
17
3
20
2
6
4
9
7
19
14
12
15
10
17
20
18
(T1 8 T2) 13 T3
18
E. Giovannetti - AlgELab-09-10 - Lez.35
11
73
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
74
Esempio di cancellazione: rotazioni a cascata.
Esempio (continua).
• Se l'albero di radice 13 è a sua volta l'albero-figlio sinistro
o destro di un altro albero, potrebbe sbilanciarlo, e così via.
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
75
Esempio di rotazioni a cascata (continua)
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
76
Esempio di rotazioni a cascata (continua)
77
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
78
13
Esempio di rotazioni a cascata (continua)
21/01/10 21.23
E. Giovannetti - AlgELab-09-10 - Lez.35
79
14
Scarica