Alberi di ricerc 161 3 5 2 4 8 10 11 2 3 4 5 8 10 11 15 25 30 31 45 47 50 Figur 6.20 Esempio di lbero Inodiinterniconduefiglimntengonoil mssimo del sottolbero sinistro ( ); i nodi interni con tre figli mntengono il mssimo del sottolbero sinistroediquellocentrle ( ed ). 6.4 Alberi 2-3 Nei Prgrfi 6.2 e 6.3 bbimo visto come usre rotzioni per implementre le operzioni su dizionri in tempo logritmico (nel cso peggiore o mmortizzto). In questo prgrfo studieremo un tecnic lterntiv lle rotzioni, bst sull ide di permettere un mggioreflessibilitànelgrdodeinodi. Seilgrdo non è vincolto d essere,ilbilncimentopuòinftti essere mntenuto trmite opportune seprzioni (split)efusioni(fuse)dinodi. Definizione 6.6 (Albero -) Un lbero - èunlberocheincuiogni nodo interno h o figli e tutti i cmmini rdice-fogli hnno l stess lunghezz. Dimostrimo innnzitutto un limitzione sull ltezz degli lberi Lemm 6.5 Si un lbero - con nodi, foglie ed ltezz. Leseguenti disuglinze sono soddisftte d, e : e. Dimostrzione. Mostrimo l limitzioni contempornementeusndo induzione su. Se,l lberoconsistediunsingolo nodo, che è nche fogli, e le disuguglinze sono bnlmente verificte. Supponimo or che l ipotesi induttiv si verifict sino d ltezz econsiderimounlbero - di ltezz.si ottenuto d eliminndo l ultimo livello e sino e il numero di nodi e di foglie di,rispettivmente.peripotesi induttiv, e.poichéognifoglidi h lmeno due d l più tre figli in, vremo,ovvero.poiché, è fcile completre l dimostrzione sfruttndo l ipotesi induttiv su. Usndo l limitzione sul numero di nodi dimostrt nellemm6.5,epssndo l logritmo, ottenimo che l ltezz di un lbero - è. Le chivi e gli elementi del dizionrio sono ssegnti lle foglie dell lbero, in modo che le chivi ppino in ordine crescente d sinistr verso destr. Ogni nodo interno mntiene invece due informzioni supplementri: e. è l m s s i m c h i v e n e l s ottolbero rdicto nel figlio sinistro di,e è
162 Cpitolo 6 lgoritmo serch - pple 1. if è un fogli then 2. if pple then return 3. else return null 4. -esimo figlio di 5. if pple then return serch pple 6. else if h due figli oppure pple then return serch pple 7. else return serch pple Figur 6.21 Implementzione dell operzione serch in un lbero l mssim chive nel sottolbero rdicto nel figlio centrle di.unesempioè mostrto in Figur 6.20. Grzie lle informzioni ed,unricercpuòessere implementt in un mnier simile gli lberi binri di ricerc clssici. serch Confrontimo l chive cerct si con che con.se proseguimo nel sottolbero sinistro; se proseguimo nel sottolbero centrle; ltrimenti proseguimo nel sottolbero destro. Lo pseudocodice è mostrto in Figur 6.21. Il tempo richiesto d serch è proporzionle ll ltezz dell lbero, che è per il Lemm 6.5. 6.4.1 Fusioni e seprzioni di nodi In questo prgrfo mostreremo come sfruttre le possibili vrizioni di grdoper ggiornre un lbero - frontediinserimentiecncellzioni di elementi. insert Creimo un nuovo nodo con elemento echive. Loclizzimolcorrett posizione per l inserimento di ricercndo l chive nell lbero. Identifichimo così un nodo,sulpenultimolivello,che dovrebbe diventre genitore di. Abbimo or due csi: h due figli: possimo ggiungere come nuovo figlio di,inserendolo opportunmente come figlio sinistro, centrle, o destro in modo d mntenere l ordinmento crescente delle chivi. Questo può comportre dover ggiornre ivlori ed del nodo edeisuointenti. h tre figli: non potendo ggiungere un ulteriore figlio, seprimoilno- do in due, con un operzione chimt split. Creimo un nuovo nodo e clcolimo l posizione corrett che dovrebbe vere rispetto i tre figli di. Rendimo le due foglie con chivi minime figlie di elerimnentiduefiglie di.attcchimopoi come figlio del pdre di immeditmente precedente. Seilpdredi vev due figli, possimo fermrci. Altrimenti, dobbimo
Alberi di ricerc 163 11 3 5 2 4 8 10 15 25 30 31 45 47 50 3 5 11 2 4 8 10 15 25 30 31 45 47 50 3 9 11 2 4 8 10 15 25 30 31 45 47 50 5 3 9 11 2 4 8 10 15 25 30 31 45 47 50 Figur 6.22 Inserimento del nodo con chive in un lbero eseguire un nuovo split sul pdre di,procedendonell lberoverso l lto. Nel cso peggiore, qundo tuttiinodilungoilcmmino vevno già tre figli, ggiungeremo ll lbero un nuov rdice. I vlori e dei nodi incontrti lungo l rislit vnno nch essi ggiornti opportunmente. Un esempio di inserimento è illustrto in Figur 6.22. Lo pseudocodice dell procedur split,richimtsuunnodo con figli, è inoltre mostrto in Figur 6. (lo pseudocodice non mostr come ggiornre i cmpi ed di ciscun nodo: ggiungere le opportune istruzioni può essere un utile esercizio). Poiché ciscuno split richiede tempo costnte e l ltezz dell lbero è, nelcso peggiore l inserimento richiede tempo.
164 Cpitolo 6 lgoritmo split 1. cre un nuovo nodo 2. si l -esimo figlio di in, 3. rendi e figli sinistro e destro di 4. if null then 5. cre un nuovo nodo 6. rendi e figli sinistro e destro di 7. else 8. ggiungi come figlio di immeditmente precedente 9. if h quttro figli then split Figur 6. Implementzione dell procedur usiliri split ust per implementre l inserimento in un lbero delete L operzione di cncellzione è simmetric quell diinserimento.si contenente l elemento d eliminre. Abbimo tre csi: il nodo è l r d i c e : b s t r i m u o v erl ottenendo un lbero vuoto. Il pdre di h tre figli: è possibile rimuovere,ggiornndoeventulmente i cmpi e di edeisuointenti(vedifigur 6.24). Il pdre di h due figli: se il pdre di è l r d i c e, b s t e l i m i n re esuopdre, lscindo l ltro figlio comerdice. Altrimenti, eseguimo un operzione simmetric llo split,chechimeremofuse. Si il pdre di ;ssumimo che bbi un frtello ll su sinistr (nessun nodo può inftti essere figlio unico, e il cso in cui bbi un unico frtello destr viene trttto in modo b b c b () c d d (b) b c d e c d e c c (c) b c d Figur 6.24 Cncellzione d un lbero c d -: vricsi.
Alberi di ricerc 165 15 25 38 30 31 35 45 47 30 31 35 38 45 47 50 38 30 31 35 45 47 30 31 35 38 45 47 50 38 30 31 35 45 47 30 31 35 38 45 47 50 Figur 6.25 Cncellzione del nodo con chive d un lbero simile). Se h tre figli, spostimo il figlio destro di come figlio sinistro di e cncellimo (vedi Figur 6.24b). Altrimenti, dopo ver rimosso, ttcchimo l unico figlio rimnente di come figlio destro di erichimimo ricorsivmente l procedur per cncellre (vedi Figur 6.24c). Un esempio di cncellzione è mostrto in Figur 6.25. Anche in questo cso, poiché ciscun fuse richiede tempo costnte e l ltezz dell lbero è, nel cso peggiore l cncellzione richiede tempo. Rissumimo i dettgli sull implementzione dell clsse Albero in Figur 6.26 e le prestzioni degli lberi - nel seguente teorem. Teorem 6.5 Un lbero - con nodi support operzioni serch, insert e delete in tempo nel cso peggiore. 6.5 B-lberi In questo prgrfo ffronteremo il problem di come relizzre un dizionrio in memori secondri. Come bbimo visto nel Prgrfo 2.8 del Cpitolo 2, l
166 Cpitolo 6 clsse Albero implement Dizionrio: dti: un lbero - con nodi: le foglie mntengono le chivi e gli elementi del dizionrio, mentre i nodi interni mntengono le informzioni supplementri e. operzioni: serch trcci un cmmino nell lbero usndo l proprietà d i r i c e r c e l e i n - formzioni e per decidere se proseguire nel sottolbero sinistro, centrle (se esiste) o destro. insert cre un nuovo nodo con elemento echive,eloggiungell lbero come fogli mntenendo l proprietà di ricerc. Se il pdre di vev già tre figli, sepr il nodo in due trmite uno split epropg le seprzioni verso l lto, fino l primo nodo con due figli o fino ll crezione di un nuov rdice. delete elimin il nodo con elemento.seilpdre di vev solo due figli, uniscilo l frtello trmite un operzione fuse e propg le fusioni verso l lto, fino l primo nodo con tre figli o fino ll cncellzione dell rdice. Figur 6.26 Dizionrio relizzto medinte lberi memori secondri è tipicmente molto più grnde di quell principle,m ccedervi è molto più costoso in termini di tempo.è quindi importnte minimizzre il numero di letture e scritture su memori estern (I/O). Per mmortizzre il tempo speso in ogni ccesso, idtisonogestitiinblocchi di dimensione : perpoter sfruttre questo ftto, è importnte che un lgoritmo o un struttur dti esibisc loclità nell ccesso i dti. Le implementzioni dei dizionri proposte nei prgrfi precedenti non esibiscono buon loclità: intuitivmente, non offrono nessun grnzi che i nodi su un certo cmmino di ricerc risiedno nello stesso blocco, e quindi si potrebbero vere I/O nel cso peggiore. Come vedremo, è possibile fre molto meglio. L ide è di umentre l informzione crico di ciscun nodo ed il grdo del nodo rendendoli proporzionli. In questo modo,potremo usre tutt l informzione contenut in ognibloccocheporteremoinmemori principle, e, poiché diminuiremo considerevolmente l ltezz dell lbero, vremo un numero minore di ccessi memori secondri. I B-lberi che presentimo in questo prgrfo sono dovuti Byer e McCreight [4] e sono un estensione nturle degli lberi - che bbimo descritto nel Prgrfo6.4.