Lez. 141 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati 2-3 BTree Copyright.

Slides:



Advertisements
Presentazioni simili
Training On Line - CONP. 2 Richiesta Da Menu: Conferimenti ad inizio anno termico > Agosto > Pluriennali > Nuova Richiesta Si accede alla pagina di Richiesta.
Advertisements

Dipartimento di Ingegneria Idraulica e Ambientale - Universita di Pavia 1 Caduta non guidata di un corpo rettangolare in un serbatoio Velocità e rotazione.
Strutture dati per insiemi disgiunti
Algoritmi e Strutture Dati
1 MeDeC - Centro Demoscopico Metropolitano Provincia di Bologna - per Valutazione su alcuni servizi erogati nel.
TAV.1 Foto n.1 Foto n.2 SCALINATA DI ACCESSO ALL’EREMO DI SANTA CATERINA DEL SASSO DALLA CORTE DELLE CASCINE DEL QUIQUIO Foto n.3 Foto n.4.
1 Pregnana Milanese Assessorato alle Risorse Economiche Bilancio Preventivo P R O P O S T A.
Frontespizio Economia Monetaria Anno Accademico
1 la competenza alfabetica della popolazione italiana CEDE distribuzione percentuale per livelli.
Lez. 121 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Progettazione.
Algoritmi Avanzati Grafi e Alberi
Lez. 31 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
Lez. 131 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Rappresentazione.
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
Training On Line – CONA. 2 Richiesta Da Menu: Conferimenti ad inizio anno termico > Agosto > Annuali > Nuova Richiesta Si accede alla pagina di Richiesta.
RB-alberi (Red-Black trees)
Alberi binari di ricerca
Heap binomiali.
Implementazione dell algortimo di Viterbi attraverso la soluzione del problema di cammino mi- nimo tramite software specifico. Università degli studi di.
I MATEMATICI E IL MONDO DEL LAVORO
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Stesso approccio.
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati.
Algoritmi e Strutture Dati
Algoritmi e Strutture Dati
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati.
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl 1 Stesso approccio.
Capitolo 6 Alberi di ricerca Algoritmi e Strutture Dati.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Liste.
EIE 0607 III / 1 A B P a = 30 P b = 35 t = 2, tc = 1 Questo può essere un equilibrio? No! Politiche di un paese importatore: una tariffa allimportazione.
Esercizi su alberi binari
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Copyright © The McGraw - Hill Companies, srl Capitolo 6 Interrogazioni.
Il problema del dizionario
Camil Demetrescu, Irene Finocchi, Giuseppe F. ItalianoAlgoritmi e strutture dati Capitolo 4 Ordinamento: Heapsort Algoritmi e Strutture Dati.
Algoritmi e Strutture Dati
Capitolo 9 Il problema della gestione di insiemi disgiunti (Union-find) Algoritmi e Strutture Dati.
Interrogazioni su un albero binario di ricerca Search(S,k) – dato un insieme S ed un valore chiave k restituisce un puntatore x ad un elemento in S tale.
Programmazione 1 9CFU – TANTE ore
Ufficio Studi UNIONCAMERE TOSCANA 1 Presentazione di Riccardo Perugi Ufficio Studi UNIONCAMERE TOSCANA Firenze, 19 dicembre 2000.
Algoritmi e Strutture Dati
Test di ipotesi X variabile casuale con funzione di densità (probabilità) f(x; q) q Q parametro incognito. Test Statistico: regola che sulla base di un.
Albero: insieme di punti chiamati NODI e linee chiamate EDGES
Algoritmi e Strutture Dati 20 aprile 2001
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Master universitario di II livello in Ingegneria delle Infrastrutture e dei Sistemi Ferroviari Anno Accademico 2012/2013 Cultura dimpresa, valutazione.
Esercizi su alberi binari
La partita è molto combattuta perché le due squadre tentano di vincere fino all'ultimo minuto. Era l'ultima giornata del campionato e il risultato era.
Heap binomiali Gli heap binomiali sono strutture dati su cui si possono eseguire efficientemente le operazioni: Make(H) : crea uno heap vuoto Insert(H,
Lezione 6 Encoder ottici
Anche la RB-Delete ha due fasi: Nella prima viene tolto un nodo y avente uno dei sottoalberi vuoto sostituendolo con la radice dellaltro sottoalbero. Per.
1 Negozi Nuove idee realizzate per. 2 Negozi 3 4.
TECNOLOGIE DELLINFORMAZIONE E DELLA COMUNICAZIONE PER LE AZIENDE Materiale di supporto alla didattica.
Bando Arti Sceniche. Per poter procedere è indispensabile aprire il testo del Bando 2ROL - Richieste On Line.
RB-insert(T, z) // z.left = z.right = T.nil Insert(T, z) z.color = RED // z è rosso. Lunica violazione // possibile delle proprietà degli alberi // rosso-neri.
LE SAI LE TABELLINE? Mettiti alla prova!.
1 Questionario di soddisfazione del servizio scolastico Anno scolastico 2011/2012 Istogramma- risposte famiglie.
21 marzo 2002 (ri-)Avvisi: Giovedi 28 marzo la lezione e sospesa. Nuovo indirizzo di Spedire messaggi e esercizi solo.
Capitolo 3 Strutture dati elementari Algoritmi e Strutture Dati Camil Demetrescu, Irene Finocchi, Giuseppe F. Italiano.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Atzeni, Ceri, Paraboschi, Torlone Basi di dati McGraw-Hill,
NO WASTE Progetto continuità scuola primaria scuola secondaria Salorno a.s. 2013_
Numeri Interi senza segno
A.P. cat. B - 1 Per chi vuole: Libro di testo D.P. Curtis, K. Foley, K. Sen, C. Morin Informatica di base 2° edizione Mc Graw-Hill Companies.
alberi completamente sbilanciati
Algoritmi e Strutture Dati
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
Capitolo 6 Alberi di ricerca Algoritmi e Strutture Dati.
Prof.ssa Rossella Petreschi Lezione del 17 /10/2014 del Corso di Algoritmica Lezione n°5.
Transcript della presentazione:

Lez. 141 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati 2-3 BTree Copyright © by Claudio Salati.

2 Rappresentazione di alberi Negli esercizi si e' visto come, aumentando le informazioni presenti in un un nodo di albero binario, aggiungendo una informazione di dimensione del sottoalbero sia possibile inserire nuovi elementi in un albero binario mantenendolo bilanciato. N.B.: la procedura di inserimento bilanciato vista negli esercizi non consente pero' di mantenere ordinato l'albero! Negli esercizi si e' anche visto come una infomazione di nodo arricchita l'informazione sull'identita' del proprio genitore consenta anche una navigazione piu' efficiente nell'albero. consente ad esempio di localizzare facilmente nell'insieme l'elemento immediatamente successivo ad un elemento dato.

3 Cosa si vorrebbe quello che si vorrebbe e' potere effettuare inserimenti, rimozioni, ricerche in un albero ordinato (in termini di valori o in termini di posizione degli elementi) mantenendolo anche bilanciato in realta': mantenendo l'altezza dell'albero logaritmica nel numero di nodi in esso contenuti. notare che un albero potrebbe anche essere visto come una struttura di indiciamento di un vettore di dimensione dinamica: consentendoci in tempo logaritmico di: leggere il k-esimo elemento del vettore, se questo elemento esiste. scrivere il k-esimo elemento del vettore, se questo elemento esiste. inserire un nuovo elemento in una qualunque posizione del vettore (in particolare in fondo al vettore), estendendo cosi il vettore. eliminare un elemento in una qualunque posizione del vettore, riducendone cosi' la dimensione. in realta' e' proprio quello che succede nel file system Unix!

4 La risposta: BTree Un 2-3 BTree e' un albero ordinato con le seguenti proprieta': i dati (l'informazione inserita nell'albero) sono contenuti solo nelle foglie dell'albero (questa e' in realta' una semplificazione). tutte le foglie dell'albero si trovano alla stessa profondita'. ogni nodo non terminale (che non e' una foglia) ha 2 o 3 figli. i nodi non terminali dell'albero mantengono la strutturazione della base dati. Per mantenere la strutturazione della base dati i nodi non terminali possono/devono contenere informazioni strutturali addizionali. Le informazioni mantenute dai nodi non terminali dipendono dall'ADT che si vuole realizzare tramite il BTree, e.g.: un vettore di dimensioni variabili una tabella associativa (una mappa chiave informazione) l'efficienza del BTree e' legata all'informazione strutturale mantenuta nei nodi non terminali.

5 Informazione strutturale Informazione strutturale che puo' essere mantenuta sui nodi non terminali tipo del nodo: non-terminale (per una foglia sarebbe: terminale). altezza del nodo (N.B.: sostituisce linformazione precedente, in quanto e =0 per una foglia, 0 per un nodo non terminale). numero di foglie (elementi di informazione) sotteso dal nodo per un ADT vettore. elemento di informazione minimo e/o massimo contenuto nel nodo per un ADT tabella asoociativa. N.B.: ogni nodo mantiene (deve mantenere) informazioni solo sul proprio sotto-albero. E' ovvio che l'informazione mantenuta in un nodo deve essere aggionata congruentemente quando la struttura del suo sotto- albero viene modificata. perche aggiungo o cancello una foglia

6 Informazione strutturale In quanto appartenenti ad un albero tutti i nodi, terminali o meno, devono mantenere le relazioni caratteristiche dell'albero stesso: relazione padre figli 2 o 3 in caso di nodo non terminale, e ovviamente occorre anche sapere quanti figli ha il nodo 0 in caso di foglia relazione figlio padre

7 BTree: una possibile definizione struct header { elemento max; int size; struct node *child; }; struct inode { int kidsNo; struct header children[3]; }; struct node { int tipo; #define ELEMENTO 0 #define NODO 1 union {elemento val; struct inode inodo; } choice; }; #define STRUCT_NODE (sizeof(struct node)) typedef struct node *bTree;

8 Esempio 2-3 BTree in cui viene mantenuta l'informazione sul numero di foglie (elementi di informazione) sotteso dal nodo. e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5

9 Esempio: come si trova il k-esimo elemento?1 Supponiamo di volere trovare il valore del k-esimo elemento informativocontenuto nel BTree, con k=9. Lelemento v[9] del vettore v concretamente rappresentato dal BTree parto dal nodo radice n0, e voglio l'elemento di indice 9 nel relativo sotto-albero 9 12: l'elemento esiste 9 > 7: l'elemento non e' nel primo sotto-albero di n0 9 (7+5): l'elemento e' nel secondo sotto-albero di n0, cioe' n2, ed e' l'elemento (9-7), cioe' 2, di questo sottoalbero Continua alla pagina seguente

10 Esempio: come si trova il k-esimo elemento?2 Continua dalla pagina precedente vado dal nodo n2, e voglio l'elemento di indice 2 nel relativo sotto- albero 2 5: l'elemento esiste 2 2 : l'elemento e' nel primo sotto-albero di n2, cioe' n6, ed e' l'elemento (2-0), cioe' 2, di questo sottoalbero vado dal nodo n6, e voglio l'elemento di indice 2 nel relativo sotto- albero 2 2: l'elemento esiste i figli sono foglie: l'elemento e' la secoda foglia di questo sottoalbero, cioe' l'elemento e9

11 Complessita' delle operazioni su un 2-3 BTree Durante l'operazione abbiamo visitato solo i nodi che vanno dalla radice alla foglia desiderata. cioe' un numero di nodi pari all'altezza dell'albero. l'altezza di un 2-3 BTree e' del logaritmo in base 2 del numero delle sue foglie, in quanto ogni nodo non terminale ha almeno 2 foglie. pertanto, se le operazioni sul BTree coinvolgono solo nodi sul percorso dalla radice alla foglia selezionata, queste operazioni hanno complessita O(log(n)) rispetto al numero n di elementi informativi contenuti nell'albero. notare che il numero complessivo di nodi dell'albero puo' arrivare fino a 2*n-1, essendo che i nodi non terminali sono al piu' n-1. Esercizio: Quanti nodi ci sono un un 2-3 Btree di altezza h? Dualmente, quanto e alto un 2-3 Btree che ha n foglie?

12 Ricerca di un elemento (key-based) struct node *search_2_3(bTree t, elemento e) { if (t == NULL) return (NULL); else if (t->tipo == ELEMENTO) if (t->choice.val == e) return (t); else return (NULL); else { // t->tipo == NODO for (int k = 0; k choice.inodo.kidsNo; k += 1) { if (t->choice.inodo.children[k].max >= e) return (search_2_3(t->choice.inodo.children[k].child, e)); // end if } return (NULL); }

13 Esempio 1: inserimento di un nuovo elemento.1 Supponiamo di volere inserire un nuovo elemento informativo eN in posizione 4. e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN

14 Inserimento di un nuovo elemento1.2 Poiche' il nodo n4 ha solo due figli possiamo aggiungergliene ancora 1. Ovviamente occorre aggiornare le informazioni strutturali contenute in n4, che ora contiene 3 foglie, n1, che ora contiene 8 foglie, ed n0, che ora contiene 13 foglie. Notare che si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia inserita e la radice. Per cui la complessita' dell'operazione e' O(log(n))

15 Inserimento di un nuovo elemento1.3 Inserimento di un nuovo elemento informativo eN in posizione 4. e1 n n1 - 8n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 3n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN

16 Esempio 2: inserimento di un nuovo elemento1 Supponiamo di volere inserire un nuovo elemento informativo eN in posizione 11. e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN

17 Inserimento di un nuovo elemento2.2 Poiche' il nodo n7 ha gia' 3 figli non possiamo aggiungergliene ancora 1. Quindi il nodo n7 deve essere suddiviso in 2 nodi, n7' e n7", ciascuno con due figli (e due foglie sottese). A questo punto il nodo n2 si trova ad avere 3 figli, il che e' legittimo. Ovviamente occorre correggere le informazioni strutturali di n2, che ora contiene 6 foglie, ed n0, che ora contiene 13 foglie. Notare che si sono dovute effettuare suddivisioni, o si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia inserita e la radice. Per cui la complessita' dell'operazione e' O(log(n))

18 Inserimento di un nuovo elemento2.3 Inserimento di un nuovo elemento informativo eN in posizione 11. e1 n n1 - 7n2 - 6 n6 - 2n7' - 2n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN n7" - 2

19 Esempio 3: inserimento di un nuovo elemento1 Supponiamo di volere inserire un nuovo elemento informativo eN in posizione 7. e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN

20 Inserimento di un nuovo elemento3.2 Poiche' il nodo n5 ha gia' 3 figli non possiamo aggiungergliene ancora 1. Quindi il nodo n5 deve essere suddiviso in 2 nodi, n5' e n5", ciascuno con due figli (e due foglie sottese). A questo punto pero' il nodo n1 si troverebbe ad avere 4 figli, il che e' illegittimo, per cui anch'esso andra' suddiviso in due nodi n1' e n1", entrambi con 2 figli. Adesso n0 ha 3 figli, n1', n1" e n2: ma questo e' perfettamente legittimo. Ovviamente occorre correggere le informazioni strutturali di n0, che ora contiene 13 foglie. Ed occorre anche compilare correttamente le informazioni strutturali di n1' e n1", indicando il numero corretto di foglie da essi sottese. Sia n1' che n1" contengono quattro foglie

21 Inserimento di un nuovo elemento3.3 Notare che, anche in questo caso, si sono dovute effettuare suddivisioni, o si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia inserita e la radice. Per cui la complessita' dell'operazione e' O(log(n))

22 Inserimento di un nuovo elemento3.4 Inserimento di un nuovo elemento informativo eN in posizione 7. e1 n n1' - 4n2 - 5 n6 - 2n7 - 3n5' - 2n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5 eN n5" - 2 n1" - 4

23 Esempio 4: inserimento di un nuovo elemento1 Supponiamo di volere inserire un nuovo elemento informativo eN in posizione 7 nell'albero costituito dai nodi non terminali n0, …, n3, e dalle foglie e1, …, e7. e1 n0 - 7 n3 - 3n2 - 2n1 - 2 e6e7e2e3e4e5eN

24 Inserimento di un nuovo elemento4.2 Poiche' il nodo n3 ha gia' 3 figli non possiamo aggiungergliene ancora 1. Quindi il nodo n3 deve essere suddiviso in 2 nodi, n3' e n3", ciascuno con due figli (e due foglie sottese). A questo punto pero' il nodo n0 si troverebbe ad avere 4 figli, il che e' illegittimo, per cui anch'esso andra' suddiviso in due nodi n0' e n0", entrambi con 2 figli. Avendo suddiviso la radice dell'albero in due, e' necessario creare una nuova radice r che abbia n0' e n0" come sotto-alberi in questo modo si e' dovuto aumentare di uno l'altezza dell'albero. Ed occorre anche compilare correttamente le informazioni strutturali di n0', n0" e r indicando il numero corretto di foglie da essi sottese. sia n0' che n0" contengono quattro foglie. r sottende 8 foglie

25 Inserimento di un nuovo elemento4.3 Si ottiene quindi l'albero indicato di sotto. e1 n0 - 4 n3' - 2n2 - 2n1 - 2 e6e7e2e3e4e5eN n3" - 2 n0 - 4 r - 8

26 Inserzione di un elemento (key-based) struct result { int newEl; #define NONE 0 #define TOLEFT 1 #define TORIGHT 2 struct header old; struct header new; };

27 Inserzione di un elemento (key-based) struct node *getLeaf(elemento e) { struct node *temp = malloc(STRUCT_NODE); temp->tipo = ELEMENTO; temp->choice.val = e; return (temp); } struct header makeLeafHeader(struct node *n) { struct header head; head.size = 1; head.child = n; head.max = n->choice.val; return (head); }

28 Inserzione di un elemento (key-based) struct node *getNewNode(struct header h0, struct header h1) { struct node *temp = malloc(STRUCT_NODE); temp->tipo = NODO; temp->choice.inodo.kidsNo = 2; temp->choice.inodo.children[0] = h0; temp->choice.inodo.children[1] = h1; return (temp); } struct header getNodeAndMakeHeader(struct header h1, struct header h2) { struct header temp; temp.size = h1.size + h2.size; temp.max = h2.max; temp.child = getNewNode(h1.child, h2.child); return (temp); }

29 Inserzione di un elemento (key-based) void setNONEResult(struct node *n, struct result *res) { res->newEl = NONE; res->old.child = n; if (n->choice.inodo.kidsNo == 2) { res->old.max = n->choice.inodo.children[1].max; res->old.size = n->choice.inodo.children[0].size + n->choice.inodo.children[1].size; } else { //.kidsNo == 3 res->old.max = n->choice.inodo.children[2].max; res->old.size = n->choice.inodo.children[0].size + n->choice.inodo.children[1].size + n->choice.inodo.children[2].size; }

30 Inserzione di un elemento (key-based) void setHeader2(struct node *n, struct header *h) { h->max = n->choice.inodo.children[1].max h->size = n->choice.inodo.children[0].size + n->choice.inodo.children[1].size; h->child = n; }

31 Inserzione di un elemento (key-based) int getPos(struct node*n, elemento e) { int pos; for(pos = 0; pos choice.inodo.kidsNo; pos += 1) if (e choice.inodo.children[pos].max) break; // end if // end for return (pos); }

32 Inserzione di un elemento (key-based) void insert_2_3(bTree *t, elemento e) { if (*t == NULL) { *t = getLeaf(e); } else if ((*t)->tipo == ELEMENTO) { struct header oldH = makeLeafHeader(*t); struct header newH = makeLeafHeader(getLeaf(e)); if (e > (*t)->choice.val) { *t = getNewNode(oldH, newH); } else { *t = getNewNode(newH, oldH); } } else { // tipo == NODO // continua alla prossima pagina

33 Inserzione di un elemento (key-based) // continua void insert_2_3(bTree *t, elemento e) // tipo == NODO struct result res = nodeInsert(*t, e); switch (res.newEl) { case NONE : break; case TOLEFT : { *t = getNewNode(res.new, res.old); break; } case TORIGHT : { *t = getNewNode(res.old, res.new); break; }

34 Inserzione di un elemento (key-based) struct result nodeInsert(struct node *n, elemento e) { struct result res; if (n->choice.inodo.children[0].size == 1) { // i figli sono foglie int pos = getPos(n, e); if (n->choice.inodo.kidsNo == 2) { // i figli sono foglie e sono 2 for (int shift = 3; shift > pos; shift -= 1) n->choice.inodo.children[shift] = n->choice.inodo.children[shift-1]; // end for n->choice.inodo.children[pos] = makeLeafHeader(getLeaf(e)); n->choice.inodo.kidsNo = 3; setNONEResult(n, &res); } else { // i figli sono foglie e sono 3 // continua nella pagina seguente

35 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // i figli sono foglie e sono 3 struct header newHead = makeLeafHeader(getLeaf(e)); int pos = getPos(n, e); if (pos <= 1) { res.newEl = TOLEFT; if (pos == 0) { res.new = getNodeAndMakeHeader (newHead, n->choice.inodo.children[0]); } else { res.new = getNodeAndMakeHeader (n->choice.inodo.children[0], newHead); } n->choice.inodo.kidsNo = 2; n->choice.inodo.children[0] = n->choice.inodo.children[1]; // continua alla pagina seguente

36 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i figli sono foglie e sono 3 // continua if (pos <= 1) n->choice.inodo.children[1] = n->choice.inodo.children[2]; res.old.size = 2; res.old.max = n->choice.inodo.children[1].child->choice.val; res.old.child = n; } else { // pos >= 2 // continua alla pagina seguente

37 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i figli sono foglie e sono 3 // pos >= 2 res.newEl = TORIGHT; if (pos == 2) { res.new = getNodeAndMakeHeader (newHead, n->choice.inodo.children[2]); } else { res.new = getNodeAndMakeHeader (n->choice.inodo.children[2], newHead); } n->choice.inodo.kidsNo = 2; res.old.size = 2; res.old.max = n->choice.inodo.children[1].child->choice.val; res.old.child = n; } } // end if ha 2 o 3 figli

38 Inserzione di un elemento (key-based) // continua struct result nodeInsert() } else { // i suoi figli non sono foglie if (e choice.inodo.children[0].max) { // si inserisce nel primo figlio res = nodeInsert(n->choice.inodo.children[0].child, e); if (res.newEl == NONE) { n->choice.inodo.children[0] = res.old; setNONEResult(n, &(res.old)); // } // continua alla pagina seguente

39 Inserzione di un elemento (key-based) // continua struct result nodeInsert() } else { // continua i suoi figli non sono foglie // continua si inserisce nel primo figlio } else if(res.newEl == TOLEFT) { if (n->choice.inodo.kidsNo == 2) { n->choice.inodo.children[2] = n->choice.inodo.children[1]; n->choice.inodo.children[1] = res.old; n->choice.inodo.children[0] = res.new; setNONEResult(n, &(res.old)); } else { // kidsNo == 3 cioe split // continua alla pagina seguente

40 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i suoi figli non sono foglie // continua si inserisce nel primo figlio // kidsNo == 3 cioe split n->choice.inodo.children[0] = n->choice.inodo.children[1]; n->choice.inodo.children[1] = n->choice.inodo.children[2]; n->choice.inodo.kidsNo = 2; res.newEl = TOLEFT; res.new = getNodeAndMakeHeader(res.new, res.old); setHeader2(n, &(res.old)); } } else { // continua alla pagina seguente

41 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i suoi figli non sono foglie // continua si inserisce nel primo figlio // res.newEl == TORIGHT if (n->choice.inodo.kidsNo == 2) { n->choice.inodo.children[2] = n->choice.inodo.children[1]; n->choice.inodo.children[0] = res.old; n->choice.inodo.children[1] = res.new; setNONEResult(n, &(res.old)); } else { // continua alla pagina seguente // kidsNo == 3 cioe split

42 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i suoi figli non sono foglie // continua si inserisce nel primo figlio // continua res.newEl == TORIGHT // kidsNo == 3 cioe split n->choice.inodo.children[0] = n->choice.inodo.children[1]; n->choice.inodo.children[1] = n->choice.inodo.children[2]; n->choice.inodo.kidsNo = 2; res.newEl = TOLEFT; res.new = getNodeAndMakeHeader(res.old, res.new); setHeader2(n, &(res.old)); } } // end if res

43 Inserzione di un elemento (key-based) // continua struct result nodeInsert() } else if (e choice.inodo.children[1].max || n->choice.inodo.kidsNo <= 2) { // i suoi figli non sono foglie // si inserisce nel secondo figlio res = nodeInsert(n->choice.inodo.children[1].child, e); if (res.newEl == NONE) { n->choice.inodo.children[1] = res.old; setNONEResult(n, &(res.old)); } else if(res.newEl == TOLEFT) { if (n->choice.inodo.kidsNo == 2) { n->choice.inodo.kidsNo = 3; n->choice.inodo.children[2] = res.old; n->choice.inodo.children[1] = res.new; setNONEResult(n, &(res.old)); } else { // continua alla pagina seguente

44 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i suoi figli non sono foglie // continua si inserisce nel secondo figlio // kidsNo == 3 cioe split res.new = getNodeAndMakeHeader (n->choice.inodo.children[0], res.new); n->choice.inodo.children[0] = res.old; n->choice.inodo.children[1] = n->choice.inodo.children[2]; n->choice.inodo.kidsNo = 2; res.newEl = TOLEFT; setHeader2(n, &(res.old)); } } else { // continua alla pagina seguente

45 Inserzione di un elemento (key-based) // continua struct result nodeInsert() // continua i suoi figli non sono foglie // continua si inserisce nel secondo figlio // res.newEl == TORIGHT if (n->choice.inodo.kidsNo == 2) { n->choice.inodo.kidsNo = 3; n->choice.inodo.children[2] = res.new; n->choice.inodo.children[1] = res.old; setNONEResult(n, &(res.old)); } else { // kidsNo == 3 cioe split res.newEl = TORIGHT; n->choice.inodo.children[0] = n->choice.inodo.children[1]; n->choice.inodo.children[1] = res.old; n->choice.inodo.kidsNo = 2; setHeader2(n, &(res.old)); res.new = getNodeAndMakeHeader (res.new, n->choice.inodo.children[2]); } // end if res

46 Inserzione di un elemento (key-based) // continua struct result nodeInsert() } else { // i suoi figli non sono foglie // si inserisce nel terzo figlio res = nodeInsert(n->choice.inodo.children[2].child, e); if (res.newEl == NONE) { n->choice.inodo.children[2] = res.old; setNONEResult(n, &(res.old)); } else { // kidsNo == 3 cioe split // continua alla pagina seguente

47 Inserzione di un elemento (key-based) // continua struct result nodeInsert() } else { // i suoi figli non sono foglie // si inserisce nel terzo figlio // kidsNo == 3 cioe split res.newEl = TORIGHT; if (res.newEl == TOLEFT) { res.new = getNodeAndMakeHeader(res.new, res.old); } else { // res.newEl == TORIGHT res.new = getNodeAndMakeHeader(res.old, res.new); } n->choice.inodo.kidsNo = 2; setHeader2(n, &(res.old)); } } // end in quale figlio si inserisce } return (res); }

48 Esempio 5: rimozione di un elemento1 Supponiamo di volere rimuovere l'elemento di indice 5 (e5). e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5

49 Rimozione di un elemento5.1 Poiche' il nodo n5 aveva 3 figli esso rimane ancora con 2 figli, il che e' legittimo. Ovviamente occorre aggiornare le informazioni strutturali contenute in n5, che ora contiene 2 foglie, n1, che ora contiene 6 foglie, ed n0, che ora contiene 11 foglie. Notare che si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia rimossa e la radice. Per cui la complessita' dell'operazione e' O(log(n))

50 Rimozione di un elemento5.3 Rimozione dell'elemento di indice 5 (e5). e1 n n1 - 6n2 - 5 n6 - 2n7 - 3n5 - 2n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4

51 Esempio 6: rimozione di un elemento1 Supponiamo di volere rimuovere l'elemento di indice 3 (e3). e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5

52 Rimozione di un elemento6.2 Poiche' il nodo n4 aveva solo 2 figli esso rimarrebbe ancora con solo un figlio, il che e' illegittimo. Ma n4 ha almeno un fratello, e in particolare un fratello ad esso adiacente (n3 non e' adiacente a n5) se uno dei fratelli adiacenti di n4 ha 3 figli, puo' cedere a n4 il figlio adiacente nel nostro caso questo capita con n5, che puo' cedere a n4 il figlio e5 in questo modo n4 torna ad evere 2 figli, e quindi una configurazione legittima. Ovviamente occorre aggiornare anche le informazioni strutturali contenute in n1, che ora contiene 6 foglie, ed n0, che ora contiene 11 foglie. Notare che si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia rimossa e la radice. Per cui la complessita' dell'operazione e' O(log(n))

53 Rimozione di un elemento6.3 Rimozione dell'elemento di indice 3 (e3). e1 n n1 - 6n2 - 5 n6 - 2n7 - 3n5 - 2n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e4e5

54 Esempio 7: rimozione di un elemento1 Supponiamo di volere rimuovere l'elemento di indice 2 (e2). e1 n n1 - 7n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 2n3 - 2 e6e7e8e9e10e11e12e2e3e4e5

55 Rimozione di un elemento7.2 Poiche' il nodo n3 aveva solo 2 figli esso rimarrebbe ancora con solo un figlio, il che e' illegittimo. n3 ha si un fratello adiacente (n4), ma questo non ha un terzo figlio da cedergli Avendo solo 2 figli, n4 puo' pero' assorbire l'unico figlio rimasto a n3: questo porta alla scomparsa di n3. Poiche' il padre di n3 (n1) rimane comunque con 2 figli la scomparsa di n3 non richiede altre ristrutturazioni nell'albero Ovviamente occorre aggiornare anche le informazioni strutturali contenute in n1, che ora contiene 6 foglie, ed n0, che ora contiene 11 foglie. Notare che si sono dovute aggiornare le informazioni strutturali solo nei nodi che appartengono al path tra la foglia rimossa e la radice. Per cui la complessita' dell'operazione e' O(log(n))

56 Rimozione di un elemento7.3 Rimozione dell'elemento di indice 2 (e2). e1 n n1 - 6n2 - 5 n6 - 2n7 - 3n5 - 3n4 - 3 e6e7e8e9e10e11e12e3e4e5

57 Rimozione di un elemento Quando la rimozione di un nodo figlio non e' assorbibile con trasferimento di figli dai nodi adiacenti, questo porta alla scomparso del nodo padre. Ricorsivamente, la rimozione di un nodo puo' propagarsi lungo l'albero fino alla radice Nel caso la radice si trovi ad avere un solo figlio essa deve essere rimossa: il suo unico figlio diventa la radice dell'albero l'altezza dell'albero diminuisce di 1

58 BTree I 2-3 Btree rappresentano un caso particolare di k–(2k-1) BTree Il caso in cui k=2 La possibilita' di scegliere un k opportuno e' fondamentale quando la struttura di indiciamento deve essere realizzata su disco in questo caso non occorre minimizzare solo le operazioni ma anche gli accessi al disco Per rendere l'accesso piu' efficiente si possono anche distribuire le informazioni finali sui nodi intermedi e non solo sulle foglie nota che, nel nostro caso, il valore di header.max in un nodo non terminale di altezza 1 coincide con il valore contenuto nella foglia associata