Dizionari Realizzazione con alberi binari di ricerca. Alberi rosso-neri. Dizionari con gli alberi Astro, Dado, Lana, Mela, Tasto,Vela, Zappa Astro Mela Tasto Zappa Alberi binari di ricerca Gli alberi binari di di ricerca sono etichettati in in modo che i i sottoalberi sinistro e destro siano di di ricerca, e la la radice maggiorizza propriamente tutte le le etichette a sinistra ed ed è maggiorizzata da da tutte quelle a destra label( t) = { k} label(left( t)) label(right( t)) se t = Nil se t = ConsTree( k, l, r) t è di ricerca se è uoto oppure se t = ConsTree(k, l, r) e l, r sono di ricerca max(label(l)) < k < min(label(r))
Un albero di ricerca 15 6 18 3 7 17 20 2 4 13 9 ADT degli alberi binari di ricerca Tipi: Ke, Stree Operatori: Nil: oid Stree ConsTree: Ke, Stree, Stree Stree Left, Right: Stree Stree Label: Stree Ke SetLabel: Ke, Stree Stree SetLeft, SetRight: Stree, Stree Stree ADT degli alberi binari di ricerca Label(ConsTree(k, l, r)) = k Left(ConsTree(k, l, r)) = l, Right(ConsTree(k, l, r)) = r ConsTree(k, l, r) Nil SetLabel(k, t) = t Pre: t Nil, Post: Label(t ) = k, Left(t ) = Left(t), Right(t ) = Right(t) SetLeft(t, t) = t, Pre: t Nil, Post: Label(t ) = Label(t), Left(t ) = t, Right(t ) = Right(t)
Ricerca Search (k, t) // Post: ritorna true sse k label(t) if t = Nil then return false else if Label(t) = k then return true else if k < Label(t) then return Search(k, Left(t)) else return Search(k, Right(t)) Minimo Minimum (t) // Pre: t Nil // Post: ritorna il minimo in label(t) // Oss. Il minimo in t è il nodo più a sinistra if Left(t) = Nil then return Label(t) else return Minimum (Left(t)) Successore Successor (15, t) = 17 = Minimum(Left(t)) 15 6 18 3 7 17 20 2 4 13 9
Successore Successor (13, t) = 15 15 6 18 3 7 17 20 2 4 13 9 Successore Successor (k, t) // Pre: k label(t) // Post: ritorna il minimo in label(t) {k : k k} se esiste // + altrimenti return Succ(k, +, t) Succ(k, x, t) // Post: ritorna il minimo in label(t) {k : k k} se esiste // x altrimenti Successore Succ(k, x, t) // Pre: k label(t) // Post: ritorna il minimo in label(t) {k : k k} se esiste // x altrimenti if Label(t) = k then if Right(t) Nil then return Minimum(Right(t)) else return x else if k < Label(t) then return Succ (k, Label(t), Left(t)) else // Label(t) < k return Succ(k, x, Right(t))
Inserimento Insert (k, t) // Post: trasforma t nel più piccolo albero di ricerca t t.c. // t t e label(t ) = label(t) {k} t t se t è un if t = Nil then return ConsTree(k, Nil, Nil) albero che si else if Label(t) = k then return t ottiene da t omettendo un else if k < Label(t) then sottoalbero SetLeft(Insert(k, Left(t)), t), return t else SetRight(Insert(k, Right(t)), t), return t Un albero di ricerca 15 Gli inserimenti aengono sempre sulle foglie 6 18 3 7 17 20 2 4 13 5 9 Chiae inserita Cancellazione Delete (k, t) // Post: trasforma t nel più grande albero di ricerca t t.c. // t t e label(t ) = label(t) {k} if t = Nil then return t else if Label(t) = k then /* canc. in radice: casi di base */ else if k < Label(t) then SetLeft(Delete(k, Left(t)), t), return t else SetRight(Delete(k, Right(t), t), return t
Cancellazione della radice Caso 1: Caso 3: Caso 2: Cancellazione della radice Caso 1: if Left(t) = Nil then return Rigth(t) Cancellazione della radice Caso 2: else if Right(t) = Nil then return Left(t)
Cancellazione della radice Caso 3: else m (m, t ) DelMax(Left(t)) SetLabel(m, t) // rimpiazza con m l etichetta della radice SetLeft (t, t) // rimpiazza Left(t) con t = Left(t) {m} return t Cancellazione del massimo DelMax (t) // Pre: t Nil // Post: ritorna (m, t ), m = max (label(t)), // t è l albero ottenuto da t rimuoendo m if Right(t) = Nil then return (Label(t), Left(t)) else (m, t ) DelMax(Right(t)) SetRight(t, t) return (m, t) O m Alberi bilanciati O(log n) Qual è il il caso peggiore? Cosa sappiamo del caso medio? Search, Insert e Delete hanno complessità O(h) doe h è l altezza dell albero Esistono alberi (completi, quasi completi) la cui altezza h è O(log n), doe n è la cardinalità Potremmo definire bilanciati gli alberi con questa relazione altezza/cardinalità
Alberi (s)bilanciati Se inseriamo n chiai in un albero di ricerca inizialmente uoto in ordine crescente cosa si ottiene? a 1 h = n a 2 O a n Alberi bilanciati Se le n! possibili permutazioni di n chiai distinte sono equiprobabili, il tempo medio di Search, Insert e Delete è effettiamente Θ(log n) ma Sarà meglio ristrutturare! Alberi Rosso-Neri (Red-Black) Un Un albero binario di di ricerca è Rosso-Nero se se i i ertici sono rossi o neri e se: se: 1. 1. (Nero) le le foglie (NIL) sono nere 2. 2. (Rosso) ogni ertice rosso ha ha due figli neri 3. 3. (Ramo) il il numero dei dei nodi neri è uguale su su ogni ramo Per semplicità terminologica consideriamo foglia l albero uoto: i ertici interni sono allora i ertici tout court
Un albero Rosso-Nero 15 6 18 7 17 20 15) = numero di ertici (interni) neri sui rami dell albero con radice in 15 = 2 22 Il teorema degli alberi RB Teorema. L altezza di di un un albero RB di di n ertici interni (per non contare le le foglie NIL) è h 2 log log (n (n + 1) 1) Se = root(t) ed n il numero dei ertici interni di t allora: n 2 Proa: per induzione su. Il teorema degli alberi RB Teorema. L altezza di di un un albero RB di di n ertici interni (per non contare le le foglie NIL) è h 2 log log (n (n + 1) 1) = 0 t = n 2 n = 0 = 2 0 1
Il teorema degli alberi RB Teorema. L altezza di di un un albero RB di di n ertici interni (per non contare le le foglie NIL) è h 2 log log (n (n + 1) 1) > 0 u = root( left( t)), w = root( right( t)) n 2 t = oppure t = bh ( u) = w) = u) = w) = Il teorema degli alberi RB Teorema. L altezza di di un un albero RB di di n ertici interni (per non contare le le foglie NIL) è h 2 log log (n (n + 1) 1) > 0 u = root( left( t)), w = root( right( t)) n 2 t = oppure t = n = int( t) = int( left( t)) + int( right( t)) + 1 2 = 2 + 2 + 1 ip.ind. Il teorema degli alberi RB Teorema. L altezza di di un un albero RB di di n ertici interni (per non contare le le foglie NIL) è h 2 log log (n (n + 1) 1) n 2 Regole (Rosso) e (Cammino) h 2 quando = root( t) : n 2 h / 2 n 2 h / 2 n + 1 2 h / 2 2log( n + 1) h
Inserimento in un albero RB L inserimento in un albero di ricerca aiene sempre sulle foglie Inserimento in un albero RB Come è possibile aggiungere ertici mantenendo l inariante di struttura? Inserimento in un albero RB Deo colorare il nuoo ertice, e scelgo il rosso: la regola (Cammino) è sala, ma la regola (Rosso) è iolata La regola (Rosso) è locale, ma (Cammino) è globale: dunque più difficile da recuperare
Inserimento in un albero RB x u Caso 1 w Ricolorando u, x, w la regola (Cammino) è sala; la regola (Rosso) è soddisfatta in u ma non in u x w Vero, ma è più icino alla radice di! Ricolorazione Caso 1: se il padre u e lo zio w di sono rossi (e dunque il nonno x è nero) allora colora di rosso il nonno e di nero il padre e lo zio Post: l altezza nera dell albero è immutata, ma può darsi che ora il nonno sia figlio rosso di un altro ertice rosso Inserimento in un albero RB LR() u w z Poiché è figlio destro del nodo rosso, ma lo zio z è nero, ruotiamo a sinistra Caso 2 u w z Ora è ancora anomalo, ma più prossimo alla radice
Rotazione x x γ RightRotate(, t) α α β LeftRotate(x, t) β γ La rotazione sinistra/destra presera la proprietà di essere un albero di ricerca Rotazione: caso 2 Caso 2: se è figlio destro (sinistro) del ertice rosso, ma lo zio z è nero, ruota a sinistra (destra). Post: l altezza nera dell albero è immutata, ma è padre rosso di un ertice rosso (cioè ) Inserimento in un albero RB Caso 3 r w RR(r) Non potendo ricolorare subito, prima ruotiamo a destra il padre r di, poi ricoloriamo r di rosso e di nero w r Finalmente un albero RB
Rotazione: caso 3 Caso 3: se (rosso) ha un figlio sinistro (destro) rosso allora: 1. Se è la radice, allora colorala di nero 2. Se non è la radice allora ruota a destra (sinistra) il padre r di, e colora di nero ed r di rosso Post: l altezza nera dell albero è immutata, e l anomalia di rispetto alla regola (Rosso) è risolta Realizzazione di un albero RB parent ke color left right Realizzazione delle rotazioni x x γ α LeftRotate(, t) α β w.right,.right w.left if w.left Nil then w.left.parent w.parent.parent if.parent = Nil then t.root w else if =.parent.left then.parent.left w else.parent.right w w.left,.parent w LeftRotate(x, t) β γ
Analisi della complessità Insert(k, t) inserisci k in t come per gli alberi binari di ricerca O(h) ristruttura ricolorando e con rotazioni da una foglia erso la radice O(h) O ( h) + O( h) = O( h) = O(log n) Analoghe considerazioni algono per Delete, mentre Search è oiamente O(h) = O(log n) Fine