200 likes | 299 Views
Ricerca di una chiave:. Search ( x, k ) if x == nil or k == x.key return x if k < x.key return Search ( x.left , k ) else return Search ( x.right , k ). Complessità O ( h ) dove h è l’altezza dell’albero. . Si può anche fare iterativa:. Search ( x , k )
E N D
Ricerca di una chiave: Search(x, k) ifx== nilork == x.key returnx ifk < x.key returnSearch(x.left, k) else returnSearch(x.right, k) Complessità O(h) dove h è l’altezza dell’albero.
Si può anche fare iterativa: Search(x, k) whilex≠ nilandk ≠x.key ifk < x.key x= x.left else x= x.right returnx Complessità O(h) dove h è l’altezza dell’albero.
Ricerca del minimo e del massimo: Minimum(x) // x≠ nil whilex.left≠ nil x= x.left returnx Maximum(x) // x≠ nil whilex.right≠ nil x= x.right returnx Complessità O(h) dove h è l’altezza dell’albero.
Ricerca di successivo e precedente Successor(x) ifx.right≠ nil returnMinimum(x.right) y= x.p whiley≠ nilandx == y.right x= y, y= y.p returny Il precedente si ottiene cambiando right in left e Minimum in Maximum. Complessità O(h) dove h è l’altezza dell’albero.
Inserzione di un nuovo elemento Insert(T, z) // z.left = z.right = nil x = T.root, y =nil// ypadre di x whilex ≠ nil// cerco dove mettere z y = x ifz.key < y.key x = y.left elsex = y.right z.p =y // mettozal posto della fogliax ify == nil T.root=z elseifz.key < y.key y.left=z elsey.right =z Complessità O(h) dove h è l’altezza dell’albero.
Eliminazione di un elemento: Delete(T, z) // z≠ nil ifz.left == nilorz.right == nil// tolgoz y = z // che ha al più un solo figlio else// tolgo il successore di zche non ha // sottoalbero sinistro y = Successor(z), z.key =y.key // cerco l’eventuale unico figlio xdiy ify.left ==nil x = y.right else x = y.left
// mettoxal posto di y ifx ≠ nil x.p =y.p ify.p == nil T.root =x elseify == y.p.left y.p.left =x else y.p.right =x Complessità O(h) dove h è l’altezza dell’albero.
Alberi rosso-neri Le operazioni sugli alberi binari di ricerca hanno complessità proporzionale all’altezza hdell’albero. Gli alberi rosso-neri sono alberi binari di ricerca in cui le operazioni Inserte Delete sono opportunamente modificate per garantire un’altezza dell’albero h = O(log n) Bisogna aggiunge un bit ad ogni nodo: il colore che può essere rosso o nero.
Oltre ad essere alberi binari di ricerca, gli alberi rosso-neri soddisfano le proprietà: • ogni nodo è o rosso o nero; • la radice è nera; • le foglie (nil) sono tutte nere; • i figli di un nodo rosso sono entrambi neri; • per ogni nodo x i cammini da x alle foglie sue discendenti contengono tutti lo stesso numero bh(x) di nodi neri: l’altezza nera di x; • Notare che il nodo x non viene contato in bh(x) anche se è nero.
Esempio di albero rosso-nero: 26 17 41 14 21 30 47 10 16 19 23 28 38 7 12 15 20 35 39 3
nil c g b e a f d nil nil nil nil nil nil nil nil
E’ utile usare una sentinella al posto di nil 26 17 41 14 21 30 47 10 16 19 23 28 38 7 12 15 20 35 39 3 ?
c g b e a f d ? T.nil
Proprietà: Un albero rosso-nero con n nodi interni ha altezza h ≤2 log2(n+1) Dimostrazione: Osserviamo che i nodi rossi in un cammino dalla radice ralle foglie possono essere al più bh(r) e quindi h ≤ 2 bh(r). Basta quindi dimostrare che bh(r) ≤log2(n+1) ossia che n ≥2bh(r) - 1
Dimostriamo n ≥2bh(r)– 1 per induzione sulla struttura dell’albero rosso-nero. Se T = Ø la radice r è una foglia, bh(r) = 0 e n = 0 = 2bh(r) – 1
Sia T = (r,T1,T2) e siano r1ed r2 le radici di T1 e T2 ed n1 ed n2 il numero di nodi interni di T1 e T2. Allora: bh(r1) ≥ bh(r)-1 bh(r2) ≥ bh(r)-1 n = 1+ n1+ n2 Per ipotesi induttiva
Conseguenza: Su di un albero rosso-nero con n nodi interni le operazioni Search, Minimum, Maximum, Successore Predecessorrichiedono tutte tempo O(log n)
Anche le operazioni Inserte Deletesu di un albero rosso-nero richiedono tempo O(log n) ma siccome esse modificano l’albero possono introdurre delle violazioni alle proprietà degli alberi rosso-neri ed in tal caso occorre ripristinare le proprietà. Per farlo useremo delle operazioni elementari, dette rotazioni, che preservano la proprietà di albero binario di ricerca.
x y Left-Rotate(T, x) y x Left-Rotate(T, x) y = x.right// y non deve essere la sentinella T.nil x.right = y.left, y.left.p = x // y.left può essere T.nil y.p = x.p ifx.p == T.nil T.root = y elseifx == x.p.left x.p.left = y else x.p.right = y x.p = y, y.left = x Complessità (1)
x y Right-Rotate(T, y) y x Right-Rotate(T, y) x = y.left// x non deve essere la sentinella T.nil y.left = x.right, x.right.p = y // x.right può essere T.nil x.p = y.p ify.p == T.nil T.root = x elseify == y.p.left y.p.left = x else y.p.right = x y.p = x, x.right = y Complessità (1)