Alberi di ricerca di altezza logaritmica Lezione n°5 Prof.ssa Rossella Petreschi Lezione del 17 /10/2012 del Corso di Algoritmi e Strutture Dati Riferimenti: Paragrafo 7.6 del testo Kingston “Algorithms and data structures” Edizioni: Addison-Wesley Capitolo 13,18 del testo Cormen, Leiserson, Rivest “Introduzione agli algoritmi” Edizioni: Jackson Libri
Alberi Red/Black Albero Red/Black: albero RB tale che ad ogni nodo u è associato un colore (rosso o nero); ogni foglia ha colore nero; se un nodo ha colore rosso, entrambi i suoi figli hanno colore nero; ogni cammino semplice da un nodo x(non incluso) ad una foglia contiene lo stesso numero di nodi neri, bh(x) Vale: l’altezza di un albero RB è logaritmica nel numero dei suoi nodi 2
Altezza di un albero Red/Black Il sottoalbero radicato in x,SA(x), contiene almeno 2bh(x)-1 nodi Prova (per induzione su h) Passo base: se h=0, x è una foglia 2bh(x)-1 =1-1 = 0 Ipotesi induttiva 2bh(y)-1 per ogni y con h(y) < h(x) Prova: SA(x) = x+ SA(fs(x))+ SA(fd(x)) Nodi interni di SA(x) ≤ (2bh(x)-1-1)+ (2bh(x)-1-1)+1≤ 2bh(x)-1 Th: Un albero Red/Black con n nodi ha altezza O(logn) Prova: per (*) almeno metà dei nodi su un qualunque cammino dalla radice ad una foglia (esclusa la radice)devono essere neri (bh(x) ≥ h/2) e quindi n ≥ 2bh(x)-1≥ 2h/2-1 (*) se un nodo ha colore rosso, entrambi i suoi figli hanno colore nero. 3
Inserzione Si inserisce x come in un qualunque albero di ricerca e poi AVL : si ricalcolano i fattori di bilanciamento dei nodi nel cammino da x a r. Sia v il nodo più profondo con fb = +/-2. Con perno nei nodi con fb = +/-2, a partire da v e risalendo alla radice, si eseguano opportune rotazioni. R/B: x si colora di rosso e si vede se si viola (*) quando si viola (*) si tende a spostare la violazione verso l’alto iterando i seguenti passi: lo zio di x, z(x), è rosso allora commuta i colori di p(x), z(x),p(p(x)) lo zio di x, z(x), è nero allora esegui una rotazione la radice si mantiene sempre nera (*) se un nodo ha colore rosso, entrambi i suoi figli hanno colore nero. 4
Cancellazione Si cancella x come in un qualunque albero di ricerca e poi AVL : si ricalcolano i fattori di bilanciamento dei nodi nel cammino da x a r. Sia v il nodo più profondo con fb = +-2. Con perno nei nodi con fb = +-2, a partire da v e risalendo alla radice, si eseguano opportune rotazioni. R/B: se x era nero la (*) è stata violata. Si assegni nero ad y,figlio di x eliminato. y era rosso o y è la radice. Fine. y era già nero allora sposto il nero di x verso la radice a seconda che il fratello di y,w, sia rosso(r) o nero(n): se (r), lo riconduco al caso (n) scambiando i colore fra w e p(x) e ruoto a sx; se (n), ho ancora 3 casi a seconda del colore di figli di w: nn,rn (nr),rr (ogni caso si effettua tramite scambi di colore e rotazioni) (*) ogni cammino semplice da un nodo x(non incluso) ad una foglia contiene lo stesso numero di nodi neri, bh(x) 5
B-alberi B-alberi : sono progettati per operazioni su dischi magnetici o atri dispositivi di memoria secondaria ad accesso diretto;sono particolarmente efficienti nelle operazioni di Input/Output. I B-alberi sono una naturale generalizzazione degli alberi binari di ricerca bilanciati: un nodo con k chiavi ha k+1 figli; l’intervallo di chiavi gestito da un nodo è diviso in k+1 intervalli ciascuno di quali è gestito da un figlio; l’altezza cresce in modo logaritmico con il numero dei nodi dell’albero. 6
Esempio di B-albero
Perché i B-alberi? La memoria primaria (RAM) si basa su una tecnologia costosa ma che permette di eseguire le operazioni di scrittura e lettura in modo veloce (chip di memoria: dispositivi elettronici). La memoria secondaria (dischi) è più economica, ma richiede per accedere ai dati dei tempi relativamente lunghi (si debbono muovere delle componenti meccaniche per posizionare la testina).
Il Disco la superficie del disco è ricoperta di materiale magnetico; le informazioni su un disco sono organizzate in blocchi e il blocco minimo accessibile in lettura e scrittura è detto pagina; la testina di lettura/scrittura è in grado di operare mentre il disco è in movimento; la porzione di superficie che passa sotto la testina, in una posizione stabile, si dice traccia; il tempo di accesso è il tempo necessario per aspettare che una determinata pagina passi sotto la testina; la lettura e la scrittura su un disco magnetico sono completamente elettroniche.
Immagine di un disco tutti i blocchi hanno la stessa dimensione e sono definiti da: traccia , settore, faccia faccia traccia settore
Accesso alla memoria secondaria Per trattare quantità estremamente grandi di dati si devono pertanto sviluppare algoritmi che lavorino con dati memorizzati in memoria secondaria. Questi algoritmi richiedono per garantire l’efficienza computazionale: che siano minimizzati gli accessi alla memoria secondaria; che la memoria principale contenga in ogni istante un numero costante di pagine; che siano copiate le pagine selezionate dal disco nella memoria principale; Disk-Read(x) che siano riscritte sul disco le pagine modificate in memoria principale; Disk-Write(x)
Definizione di B-albero B-albero , T : albero di ricerca m-ario tale che: • ogni nodo interno,x, ha un numero n(x) di figli (t <= n(x) <=2t) e la radice, r(T), ha almeno due figli; si dice che t>=2 è il grado minimo del B-albero; gli n(x) figli di x, radici dei sottoalberi A1(x), A2(x),…, An(x)(x), sono ordinatamente raggiungibili da x tramite i puntatori c1(x), c2(x),…, cn(x)(x); • ad ogni nodo x con n(x) figli sono associate n(x) -1 chiavi ordinate (k1(x) <= k2(x) <=…<= kn(x)-1(x)); tutte le chiavi del sottoalbero Ai(x) sono maggiori della chiave ki-1(x) e minori della chiave ki(x); un nodo si dice pieno se contiene 2t-1 chiavi; tutti le foglie hanno la stessa profondità, che è l’altezza h(T) dell’albero.
h(T)<= logt ((n+1)/2) Calcolo di h(T) Un B-albero T di n>=1 chiavi e di grado minimo t>=2 ha altezza h(T)<= logt ((n+1)/2) Prova: n>= 1+ (t-1) Σ 2ti-1= la radice ha almeno 2 figli (1 chiave) e tutti gli altri nodi hanno i=1,…,h almeno t figli (t-1 chiavi), ovvero 2 nodi a profondità 1, 2t a profondità 2… = 1 + 2(t-1) Σ ti-1= serie geometrica = 1 + 2(t-1) ((th-1)/(t-1))= = 2th-1
Inserimento in un B-albero L’operazione di inserimento in un B-albero è analoga a quella già vista per un albero binario di ricerca. Si controlla x (elemento da inserire) con i valori k1(y)<= k2(y)<=…<= kn(y)-1(y) del nodo che si sta analizzando(inizialmente y = r) Se k1(y)> x, si confronta x con il primo figlio di y Se ki(y)< x < ki+1(y) si confronta x con il figlio (i+1)-esimo di y Se kn(y)-1(y)< x, si confronta x con l’ultimo figlio di y Si prosegue ricorsivamente sul cammino fintanto che non si trova libera la posizione appropriata sull’albero. Tempo O(t h(T))
Dividere un nodo calcolare l’esatta posizione di x in y; Per garantire che l’altezza del B-albero rimanga logaritmica, bisogna controllare che il nodo y in cui vogliamo inserire x non sia già pieno, ovvero non abbia più di 2t-1 chiavi. In tal caso bisogna: calcolare l’esatta posizione di x in y; prendere la chiave mediana rispetto ai 2t elementi, sia ki(y); inserire ki(y) nel nodo padre di y, p(y); spezzare il nodo y in due nodi di t chiavi ciascuno: y1contenente tutte le chiavi (chiavi di y+ la chiave x) minori di ki(y) e y2 contenente tutte le chiavi (chiavi di y+ la chiave x) maggiori di ki(y); aggiornare i puntatori di p(y) rispetto a y1 e y2 ATTENZIONE!!
Incremento dell’altezza Nell’inserire ki(y) nel nodo padre di y potremmo ritrovarci ancora una volta nella necessità di dividere il nodo (questa volta p(x)). Questo processo può propagare verso l’alto fino ad arrivare alla radice. Lo spezzamento della radice comporta l’incremento dell’altezza dell’albero dato che bisogna creare un nuovo nodo radice con una sola chiave (la chiave mediana della vecchia radice) e con due figli (i due nodi di t chiavi generati dalla vecchia radice). La complessità dell’intera operazione di inserimento (comprensiva delle eventuali divisioni di nodi) rimane dell’ordine di O(t h(T))