Alberi rosso neri API a.a. 2013/2014 Gennaio 23, 2014 Flavio Mutti, PhD
2 Sommario Definizione Operazione di rotazione Inserimento Cancellazione Temi d esame
3 Introduzione Un albero rosso-nero è un albero binario con un flag di 1 bit per ogni nodo che codifica il colore (rosso o nero) Vincoli su come assegno il colore Approssimativamente bilanciato
4 Proprietà alberi binari Sia x un nodo in un albero binario di ricerca. 1. Se y è un nodo nel sottoalbero sinistro di x, allora key[y] key[x] 2. Se y è un nodo nel sottoalbero destro di x, allora key[x] key[y]
5 Proprietà red-black 1. Ogni nodo è rosso o nero 2. La radice è nera 3. Ogni foglia (NIL) è nera 4. Se un nodo è rosso, entrambi i figli sono neri 5. Per ogni nodo, tutti i percorsi che vanno dal nodo alle foglie discendenti contengono lo stesso numero di nodi neri
6 Proprietà red-black (1) Ogni nodo è rosso o nero (2) La radice è nera
7 Proprietà red-black (3) ogni foglia è nera (basta aggiungere un livello fittizio)
8 Proprietà red-black (4) se un nodo è rosso entrambi i suoi figli sono neri
9 Proprietà red-black (5) per ogni nodo n, tutti i percorsi da n ad una qualsiasi delle sue foglie discendenti contengono lo stesso numero di nodi neri
10 Sono alberi bilanciati?
11 Sono alberi bilanciati? Un albero rosso-nero senza nodi rossi è bilanciato: tutti i suoi livelli sono completi tranne al più l ultimo, al quale può mancare qualche foglia
12 Altezza nera Definizione: l altezza nera di un nodo x, indicata con bh(x), è il numero di nodi neri lungo un percorso che inizia dal nodo x (ma non lo include) e finisce in una foglia Cormen et al. Lemma: l altezza massima di un albero red-black con n nodi interni è 2 log(n + 1) Questo lemma è importante perché ne deriva subito che la complessità di funzioni classiche (MINIMUM, MAXIMUM, SEARCH, ) sugli alberi i ricerca diventano di complessità O(log n)
13 Rotazioni Inserimento e cancellazione modificano l albero L albero risultante potrebbe violare le proprietà red-black L operazione di rotazione serve a ripristinare le proprietà red-black
14 Esempio Left rotate x α y β γ
15 Esempio Left rotate x y α y x β γ Passaggio intermedio: se y è più grande di x allora y è più grande di x e devo rispettare la proprietà degli alberi binari di ricerca
16 Esempio Left rotate x y α y x γ β γ α β Nota bene. Il padre iniziale di x diventa il padre di y e y rimane nel precedente ramo (sinistro o destro) L idea chiave è quella di mantenere la proprietà degli alberi di ricerca
17 Esempio di Right rotate y x x γ α y β γ α β
18 Esercizio Effettuare una rotazione sinistra del nodo indicato nel seguente albero 7 4 3 6 11 9 18 2 14 19 12 17 22 20
19 Soluzione 7 4 18 3 6 11 19 2 9 14 22 12 17 20
20 Inserimento di un nodo z Come per gli alberi binari di ricerca, l inserimento di un nodo z in un RB tree cerca un cammino dalla root dell albero fino al nodo p che diventerà suo padre Una volta identificato p, z viene aggiunto come figlio sinistro (se key [z] < key [p]) o destro (se key [z] > key [p]) di p e colorato di rosso Quali RB-properties possono essere violate in conseguenza di questo inserimento? Solo due: la proprietà 2 (se z viene inserito in un albero vuoto) la proprietà 4 (se z viene aggiunto come figlio di un nodo rosso) La procedura che elimina violazioni delle RB-properties dovute all inserimento di una chiave è la RB-Insert-Fixup(T, z); qui z è il nodo che da luogo alla violazione
21 Algoritmi per l inserimento
22 RB-Insert-Fixup(T,z) Ripristina la proprietà 2 colorando la root z (che in questo caso è rossa) di nero Ripristina la proprietà 4, eseguendo (ricorsivamente) delle rotazioni sul nodo z; decidiamo in base a tre possibili casi: lo zio y di z è rosso lo zio y di z è nero e z è un figlio destro lo zio y di z è nero e z è un figlio sinistro
23 RB-Insert-Fixup(T,z) Attenzione ai casi simmetrici!!!!
24 Caso 1 Inserisco z Coloro z di ROSSO P(z) è ROSSO e figlio sinistro Caso 2 Caso 3 Caso 3 Caso 1 P(z) è ROSSO e figlio destro Caso 2 Caso 3 Caso 3
25 Caso 1: lo zio y è ROSSO 1. P[z] diventa NERO 2. Y diventa NERO 3. P[P[z]] diventa ROSSO
26 Caso 2: lo zio y di z è NERO e z è un figlio destro 1. Sposto z in alto di una posizione: z = p[z] 2. Ruoto a sinistra z: LEFT-ROTATE(T,z) 3. Ora ricado nel caso 3
27 Caso 3: lo zio y di z è NERO e z è un figlio sinistro 1. Coloro P[z] di nero 2. Coloro P[P[z]] di rosso 3. Ruoto verso destra P[P[z]]
28 Caso 2 : lo zio y di z è NERO e z è un figlio sinistro 1. Sposto z in alto di una posizione: z = p[z] 2. Ruoto a destra z: RIGHT-ROTATE(T,z) 3. Ora ricado nel caso 3
29 Caso 3 : lo zio y di z è NERO e z è un figlio destro 1. Coloro P[z] di nero 2. Coloro P[P[z]] di rosso 3. Ruoto verso sinistra P[P[z]]
30 Soluzione Inserisco 41 41 Prima dell esecuzione di RB-INSERT-FIXUP 41 La radice di 41 è rossa? NO! Dopo l esecuzione di RB-INSERT-FIXUP
31 Soluzione Inserisco 38 41 38
32 Soluzione Inserisco 31 41 41 38 38 38 31 41 31 31 Applico il CASO 3
33 Soluzione Inserisco 12 38 new z 38 31 41 31 41 12 12 Applico il CASO 1
34 Soluzione 38 31 41 12 Perché alla fine coloro la radice di nero
35 Soluzione Inserisco 19 38 38 31 41 31 41 19 12 19 12 Applico il caso 2 e successivamente il caso 3
36 Soluzione Continua 38 38 31 41 31 41 19 19 12 z 12 z Applico il caso 2 e successivamente il caso 3
37 Soluzione 38 19 41 12 31 Applico il caso 2 e successivamente il caso 3
38 Soluzione Inserisco 8 38 19 41 12 31 8 Applico il caso 1
39 Cancellazione Sia z il nodo da cancellare, siano x e p l unico figlio ed il padre di z, rispettivamente (nota: se z `e una foglia, allora x è Nil). Per eliminare z, eseguiamo i seguenti passi: 1. Innanzitutto, rimuoviamo z collegando p con x (p diventa il padre di x ed x diventa il figlio di p); 2. z era rosso: possiamo semplicemente terminare perché l eliminazione di z non causa violazioni delle RB-properties 3. z era nero: potremmo causare una violazione della proprietà 5
40 Eliminazione di un rosso
41 Eliminazione di un nero e suo figlio rosso Il figlio rosso x acquisisce un extra credito diventando nero
42 Eliminazione di un nero e suo figlio nero Il figlio acquisisce un extra credito diventando doppio nero
43 Cancellazione di un nodo Per ristabilire la proprietà 5 nel caso di eliminazione di un nodo z nero, si attribuisce al nodo x (figlio di z) un extra credito Questo significa che se x è rosso lo coloriamo di nero, mentre se x è già nero assume un colore fittizio detto doppio nero, che serve per ricordarci che abbiamo collassato due nodi neri in uno. Nel calcolo della black-height un nodo doppio nero conta due volte. Infine, eseguiamo una procedura (RB-Delete-Fixup(T, x)) che spingerà, mediante rotazioni, l extra credito verso la radice dove verrà ignorato Se lungo il cammino verso la radice incontriamo un nodo rosso, esso sarà semplicemente colorato di nero
44 Algoritmi per la cancellazione
45 Algoritmi per la cancellazione Caso 1: il fratello w di x è rosso Caso 2: il fratello w di x è nero ed entrambi i figli di w sono neri Caso 3: il fratello w di x è nero, il figlio sinistro di w è rosso e il figlio destro di w è nero Caso 4: il fratello w di x è nero e il figlio destro di w è rosso
46 Algoritmi per la cancellazione Attenzione ai casi simmetrici!!!
47 Caso 2 Caso 1 Caso 3 Cancello z x è NERO e figlio sinistro Caso 2 Caso 4 Caso 3 Caso 4 Determino x, figlio del nodo cancellato Caso 4 x è NERO e figlio destro
48 Caso 1: il fratello w di x è rosso 1. Coloro w di nero 2. Coloro P[x] di rosso 3. Ruoto verso sinistra P[x] 4. W è impostato come figlio destro di P[x]
49 Caso 2: il fratello w di x è nero ed ha entrambi i figlio neri 1. Coloro w di rosso 2. Pongo x in posizione P[x]
50 Caso 2: il fratello w di x è nero ed ha entrambi i figlio neri Attenzione: B diventa nero perché compenso la rimozione di un nero da x e w
51 Caso 3: il fratello w di x è nero, il figlio sx di w è rosso e il dx è nero 1. Coloro il figlio sinistro di w di nero 2. Coloro w di rosso 3. Ruoto a destra w 4. Eseguo il caso 4
52 Caso 4: il fratello w di x è nero, il figlio sx di w è nero e il dx è rosso 1. Il colore di w diventa uguale a quello di P[x] 2. Coloro P[x] di nero 3. Coloro il figlio destro di w di nero
53 Caso 4: il fratello w di x è nero, il figlio sx di w è nero e il dx è rosso 1. Il colore di w diventa uguale a quello di P[x] 2. Coloro P[x] di nero 3. Coloro il figlio destro di w di nero 4. Ruoto a sinistra P[x]
54 Esercizio Cancellare dall albero riportato, e in ordine, i seguenti elementi: 8,12,19, 31, 38 38 19 41 12 31 8
55 Soluzione Cancello 8 38 19 41 12 31 Il nodo cancellato è rosso, non eseguo la funzione di fix.
56 Soluzione Cancello 12 38 19 41 31 Il nodo cancellato è nero, caso 2
57 Soluzione Continua 38 x 19 41 31 Il nodo cancellato è nero, caso 2
58 Soluzione Cancello 19 38 19 41 31
59 Soluzione Cancello 19 38 31 41
60 Soluzione Cancello 19 38 31 41 Non applico alcun caso perché il nodo è rosso
61 Soluzione Cancello 31 38 31 41
62 Soluzione Cancello 31 38 41 Applico il caso 2
63 Soluzione Cancello 31 38 38 41 41 Applico il caso 2
64 Soluzione Cancello 38 38 41 41
65 Temi d esame
66 Esercizio 3 del 20/2/2012 Si abbiano due alberi rosso-neri, rispettivamente di cardinalità m e n, con m << n. Si definisca, mediante opportuno pseudocodice un algoritmo che costruisca una lista (monodirezionale) ordinata in ordine crescente contenente tutti e soli gli elementi appartenenti ad entrambi gli alberi, cercando di ottenerne la miglior complessità temporale possibile. Si valuti tale complessità in funzione dei due parametri m e n.
67 Soluzione Uno schema di algoritmo per risolvere il problema posto è il seguente: Siano Tm e Tn rispettivamente i due alberi di cardinalità m e n; Si individui il massimo elemento di Tm (Questa operazione, per un albero rossonero costa O(log(m))); Si verifichi se questo elemento si trova in Tn (costo O(log(n))); Se l elemento corrente si trova anche in Tn lo si inserisca in testa alla lista, inizialmente vuota (costo O(1)); Si ripeta il ciclo precedente per tutti i successivi nodi di Tm in ordine decrescente. Si noti che per fare ciò occorre tenere traccia del nodo esaminato nella precedente iterazione del ciclo: indicando con N tale nodo, occorre quindi individuare il nodo a valore massimo a sinistra di N (assumendo che i nodi a valore minore siano a sinistra), ricerca che può comunque essere eseguite in tempo O(log(m)).
68 Soluzione La complessità totale è quindi O(m(log(m) + log(n))), che, essendo m < n è anche O(mlog(n)). Un altro algoritmo a complessità sostanzialmente equivalente potrebbe linearizzare Tm in una lista ordinata in ordine crescente (a costo O(m)) e successivamente, per ogni elemento della lista verificare se si trova in Tn (costo (O(log(n)) e in caso negativo eliminarlo dalla lista con costo O(1).
69 Soluzione Si noti che la scelta di un tale algoritmo è giustificata dall ipotesi che m << n. In caso contrario, ad esempio se n ed m fossero sostanzialmente vicini, converrebbe linearizzare entrambi gli alberi in O(n) e poi calcolarne l intersezione sempre in O(n). Tuttavia, se, ad esempio, m fosse O(log(n)), una complessità O(log2(n)) sarebbe nettamente preferibile. Si noti anche che in caso di ripetizioni entrambi gli algoritmi manterrebbero nella lista risultante il numero di occorrenze in Tm, non quello delle occorrenze in Tn.
70 Esercizio 4 10/09/2012 Si considerino gli algoritmi RB-INSERT e RB-DELETE per l inserimento e la cancellazione di nodi in e da alberi red-black. E' possibile, usando solo tali algoritmi, costruire un albero red-black fatto di esattamente 3 nodi, tutti neri? Se sì, scrivere una sequenza di invocazioni di RB-INSERT e RB-DELETE che crea l albero desiderato, motivando il perché la sequenza scritta produce la struttura richiesta.
71 Soluzione Per ottenere l'albero desiderato è sufficiente inserire 4 valori nell albero. Questo crea un albero in cui i nodi ai primi 2 livelli sono neri, e sul terzo livello c è un solo nodo di colore rosso, per esempio l albero seguente (la posizione del nodo rosso dipende dai valori inseriti, comunque è poco rilevante): Per ottenere l albero desiderato, è a questo punto sufficiente cancellare, mediante RB-DELETE, il nodo rosso.
72 Esercizio 4 27/09/2012 Si stabilisca quali sono i rapporti minimo e massimo tra il numero di nodi interni rossi e neri in un generico albero rosso-nero. Si giustifichi brevemente la risposta.
73 Soluzione Un albero può essere totalmente nero (si noti che normalmente ciò avviene solo attraverso qualche cancellazione che trasformi un nodo rosso in uno nero, perché ogni nuova inserzione in un albero totalmente nero inserisce un nodo rosso; quindi l unico modo per avere un albero totalmente nero senza operare cancellazioni è che esso consista della sola radice). In tal caso il rapporto minimo è evidentemente 0. Al contrario, il massimo numero di nodi rossi lo si può ottenere se ogni nodo nero ha entrambi i figli rossi e tutti i nodi pseudofoglie, ossia interni ma puntanti al NIL, sono rossi. In tal caso con una semplice induzione si dimostra che il rapporto massimo è 2.
74 Esercizio Dimostrare che, in un albero rosso-nero, il percorso semplice più lungo che va da un nodo x ad una foglia discendente di x ha una altezza al massimo doppia di quello del percorso semplice più breve dal nodo x a una foglia discendente
75 Soluzione Per le proprietà degli alberi rosso-neri tutti i cammini semplici da x ad una foglia discendente contengono lo stesso numero di nodi neri b. Poiché lungo un cammino semplice non possiamo avere due nodi rossi consecutivi, denotando con r il numero di nodi rossi in un cammino semplice da x ad una foglia discendente, abbiamo che 0 < r < b +1. Pertanto, per la lunghezza ò = r +b di un cammino da un nodo x ad una foglia discendente abbiamo b < l < 2b+1 Possiamo quindi concludere che il rapporto tra il più lungo e il più breve cammino semplice da x ad una foglia discendente è al più 2 + 1/b