Multi-way search tree e alberi (2,4)
In questa pagina 5
Problema degli ABR (vedi Alberi binari di ricercaAlbero binario di ricerca come albero binario proprio con entry nei nodi interni e foglie vuote; inorder crescente; TreeSearch; get, put e remove (due casi, con predecessore inorder) in Theta(h); altezza fino a n-1; esempi di inserimenti; alberi aumentati con campi size e max e algoritmi di conteggio e interrogazione in O(h).Alberi binari di ricerca →): get, put, remove costano ma può essere proporzionale a . Due rimedi: ristrutturare l'albero quando lo sbilanciamento supera una soglia (AVL, alberi rosso-neri, non trattati) oppure rendere i nodi più capienti e usare la capienza per assorbire ingressi e uscite di entry: gli alberi (2,4).
Multi-way search tree
Un multi-way search tree (MWS tree) è un albero ordinato (vedi AlberiAlbero radicato (definizione per padre e ricorsiva), terminologia (antenati, discendenti, nodi interni ed esterni, sottoalbero, albero ordinato), profondità, livello, altezza; altezza = massima profondità delle foglie; algoritmi depth e height con costo; somma dei figli = n-1; esempio di algoritmo Omega(n^2) (heightBad).Alberi →) in cui:
- ogni nodo interno ha figli;
- ogni nodo interno con figli (-nodo) memorizza entry con ;
- per ogni chiave del sottoalbero soddisfa (con , ).
Per convenzione, come negli ABR, le foglie non memorizzano entry. Un ABR è il caso in cui ogni nodo interno è un 2-nodo.
Esempio di 4-nodo: tre chiavi e quattro figli, con chiavi in , in in , in in , in .
Ricerca
Algoritmo MWTreeSearch(k, v)
Input: chiave k, nodo v Output: nodo di T_v con la chiave k, o la foglia "giusta" per k
if T.isExternal(v) then return v
siano (k1,x1), ..., (k_{d-1}, x_{d-1}) le entry di v
trova i con k_{i-1} < k <= k_i (k_0 = -infinito, k_d = +infinito)
if k = k_i then return v
else return MWTreeSearch(k, v_i)get(k): cerca come sopra; se il risultato è una foglia restituisce null, altrimenti la entry in con chiave . Complessità: il cammino ha lunghezza e in ogni nodo si cerca tra chiavi (se le entry di un nodo sono in una mappa secondaria, ad esempio una lista): .
Esempio: radice con figli , , . Cercare : tra e si va nel secondo figlio e si trova. Cercare : , si scende nel terzo figlio; , si scende nel suo primo figlio, che è una foglia: assente.
Numero di foglie
Proposizione. Un MWS tree con entry ha foglie.
Dimostrazione (induzione sull'altezza ). Base : la sola radice è una foglia, , foglia. Passo: di altezza con radice -nodo, sottoalberi con entry e foglie, altezze . Per ipotesi . Allora e .
(Se tutti i nodi interni fossero -nodi, l'albero sarebbe -ario e le foglie sarebbero , con numero di entry.)
Alberi (2,4)
Un albero (2,4) è un MWS tree tale che:
- ogni nodo interno è un -nodo con (cioè ha , o entry);
- tutte le foglie hanno la stessa profondità.
Proposizione. Un (2,4) con entry ha altezza .
Dimostrazione. Sia l'altezza (= livello delle foglie) e il numero di nodi al livello . Si ha e, poiché ogni nodo interno ha tra e figli e le foglie sono tutte a livello , . In particolare . Ma (proposizione sulle foglie). Quindi e . Dunque .
Corollario. In un (2,4) con entry MWTreeSearch e get costano (ogni nodo ha chiavi, è costante). Anche put e remove si implementano in ; la loro implementazione non è richiesta all'esame ma l'idea è semplice:
- Inserimento: si cerca la foglia e si inserisce la chiave nel nodo padre di . Se diventa un 5-nodo (4 chiavi, overflow) lo si spezza: la terza delle quattro chiavi sale al padre, le prime due restano in un nodo (a figli) e l'ultima forma l'altro (a figli). L'overflow può propagarsi verso la radice; se la radice si spezza, nasce una nuova radice e l'altezza cresce di (tutte le foglie scendono insieme: la condizione 2 resta vera). Esempio: inserendo nel nodo si ha : si spezza in e e sale nella radice, che diventa .
- Rimozione: una entry di un nodo non terminale si sostituisce con il predecessore inorder, poi si toglie la entry da un nodo con foglie come figli. Se il nodo rimane senza entry (underflow) si fa un trasferimento da un fratello con almeno figli oppure una fusione con un fratello a figli (che può propagare l'underflow in su; se la radice si svuota, l'altezza diminuisce).
Dizionario con alberi di ricerca
Un dizionario (multimap, vedi Mappe e dizionariADT mappa (chiavi distinte) con get, put, remove, keySet/values/entrySet; famiglia mappa/mappa ordinata/dizionario (multimappa); applicazioni; implementazioni semplici ma poco efficienti (lista, array indicizzato dalle chiavi); dizionario realizzato con una mappa di liste.Mappe e dizionari →) si realizza o con una mappa di coppie , o modificando ABR e (2,4) per ammettere chiavi uguali.
Confronto
| Metodo | ABR | (2,4) |
|---|---|---|
get(k) |
||
put(k, v) |
||
remove(k) |
||
remove(k, v) (dizionario) |
( = numero di valori associati alla chiave.) Nell'ABR può essere ; nel (2,4) il bilanciamento è garantito dalla struttura.
Errori comuni
- Dimenticare la condizione "tutte le foglie alla stessa profondità": senza di essa l'altezza non è logaritmica.
- Contare le foglie come entry: un MWS tree con entry ha foglie vuote.
- Cercare linearmente i figli come in un ABR: in un -nodo si cerca l'intervallo tra chiavi.
- Stimare la complessità come senza specificare per i (2,4).
Versione ripasso
- Perché: negli ABR può essere (vedi Alberi binari di ricercaAlbero binario di ricerca come albero binario proprio con entry nei nodi interni e foglie vuote; inorder crescente; TreeSearch; get, put e remove (due casi, con predecessore inorder) in Theta(h); altezza fino a n-1; esempi di inserimenti; alberi aumentati con campi size e max e algoritmi di conteggio e interrogazione in O(h).Alberi binari di ricerca →); si bilancia con nodi capienti, i (2,4).
- MWS tree: albero ordinato, ogni nodo interno è un -nodo () con chiavi e figli con ; foglie senza entry.
- Ricerca
MWTreeSearch: trova con ; se trovato, altrimenti scende in ; . - Proposizione: MWS tree con entry ha foglie (induzione: ).
- (2,4): nodi con - figli + foglie tutte alla stessa profondità. Livello ha nodi, , .
- Costi (2,4):
get,put,remove(vedi Mappe e dizionariADT mappa (chiavi distinte) con get, put, remove, keySet/values/entrySet; famiglia mappa/mappa ordinata/dizionario (multimappa); applicazioni; implementazioni semplici ma poco efficienti (lista, array indicizzato dalle chiavi); dizionario realizzato con una mappa di liste.Mappe e dizionari →). Idea: inserimento con overflow (5-nodo) spezzato (terza chiave in su); rimozione con underflow, trasferimento o fusione (non richieste all'esame). - Confronto ABR / (2,4): contro ; dizionario
remove(k,v): contro . - MWTreeSearch(, ): se esterno restituisce ; trova con ; se restituisce , altrimenti ricorre su .
- Esempio: radice , figli , , : cercare ⇒ trovato nel secondo figlio; cercare ⇒ foglia (assente). Inserire : si spezza in e e sale nella radice.
- Errori: dimenticare "foglie alla stessa profondità"; foglie contate come entry; cercare i figli come in un ABR.