Informatica 3. LEZIONE 15: Implementazione di alberi binari - BST. Modulo 1: Implementazione degli alberi binari Modulo 2: BST

Documenti analoghi
Introduzione Implementazione (1)

Informatica 3. LEZIONE 17: Alberi generici. Modulo 1: Definizione e ADT Modulo 2: Implementazione Modulo 3: Alberi e classi di equivalenza

Informatica 3. Informatica 3. LEZIONE 17: Alberi generici. Lezione 17 - Modulo 1. Introduzione. ADT dell albero generico.

Informatica 3. LEZIONE 16: Heap - Codifica di Huffmann. Modulo 1: Heap e code di priorità Modulo 2: Esempio applicativo: codifica di Huffmann

Informatica 3. Informatica 3. LEZIONE 14: Alberi binari: introduzione. Lezione 14 - Modulo 1. Definizioni. Introduzione. Definizioni e proprietà

Algoritmi e Strutture Dati Laboratorio 20/10/2008. Prof. Pier Luca Lanzi

Albero binario. Alberi binari (introduzione) Terminologia. Alberi di ricerca binaria (BST)

Strutture dati Alberi binari

Alberi binari e alberi binari di ricerca

Algoritmi e Strutture Dati & Laboratorio di Algoritmi e Programmazione

Alberi binari e alberi binari di ricerca

Alberi di ricerca. Dizionari. Definizione. Alberi binari di ricerca (BST = binary search tree) Algoritmi e Strutture Dati

Esercitazione 6. Alberi binari di ricerca

ALBERI : introduzione SOMMARIO ALBERI ALBERI. ALBERI: introduzione ALBERI BINARI: introduzione VISITE RICORSIVE DI ALBERI

Alberi binari di ricerca

Algoritmi e strutture dati

Problemi di ordinamento

Informatica 3. LEZIONE 12: Liste. Modulo 1: ADT lista e implementazione basata su array Modulo 2: Lista concatenata

LE STRUTTURE DATI DINAMICHE: GLI ALBERI. Cosimo Laneve

Alberi. CORDA Informatica. A. Ferrari. Testi da. Marco Bernardo Edoardo Bontà. Dispense del Corso di. Algoritmi e Strutture Dati

Alberi binari e alberi binari di ricerca

Multi-way search trees

Un esempio: l ADT Dizionario (mutabile) Definizione. Alberi binari di ricerca (BST = binary search tree) search(chiave k) -> elem

Algoritmi e Strutture Dati

Alberi binari di ricerca

Algoritmi e Strutture Dati. Lezione 5

Esercizi parte 3. La classe ArrayBinTree dovra implementare, tra le altre, l operazione seguente: padre: dato un nodo, restituire l indice del padre.

Alberi di ricerca. Alberi binari di ricerca. F. Damiani - Alg. & Lab. 04/05 (da C. Demetrescu et al - McGraw-Hill)

Organigramma Gerarchia. (Tree) Nessuna persona può avere più di un superiore Ogni persona può essere superiore di altre

Informatica 3. Informatica 3. LEZIONE 23: Indicizzazione. Lezione 23 - Modulo 1. Indicizzazione. Introduzione. Indicizzazione:

Per semplicità eliminiamo le ripetizioni nell'albero.

Alberi. Strutture dati: Alberi. Alberi: Alcuni concetti. Alberi: definizione ricorsiva. Alberi: Una prima realizzazione. Alberi: prima Realizzazione

Algoritmi e strutture dati

Alberi binari di ricerca

Alberi. Se x è il genitore di y, allora y è un figlio di x. Un albero binario è un albero in cui ogni nodo ha al massimo due figli.

Algoritmi e strutture dati 16 Dicembre 2004 Canali A L e M Z Cognome Nome Matricola

Esercizi su programmazione ricorsiva 3

ricerca di un elemento, verifica dell appartenenza di un elemento

L albero e un tipo astratto di dati usato per rappresentare relazioni gerarchiche.

Prova di Algoritmi e s.d. (1o anno) 17 Settembre TESTO e RISPOSTE

Algoritmi e Strutture Dati

Alberi binari di ricerca

Algoritmi e Strutture Dati. Lezione 4

Dizionari. Realizzazione con alberi binari di ricerca. Alberi rosso-neri. Ugo de' Liguoro - Algoritmi e Seprimentazioni 03/04 Lez.

Indici multilivello dinamici (B-alberi e B + -alberi) Alberi di ricerca - 1. Un esempio. Alberi di ricerca - 3. Alberi di ricerca - 2

ALBERI. Un Albero. Un grafo aciclico che non è un albero: due archi entranti in uno stesso nodo

K-d-tree A L B E R T O B E L U S S I A N N O A C C A D E M I C O

Informatica 3. LEZIONE 13: Liste doppie, pile e code. Modulo 1: Free list Modulo 2: Lista doppia Modulo 3: Pila Modulo 4: Coda

Un heap binario è un albero binario con le seguenti caratteristiche:

Algoritmi e Strutture Dati. Capitolo 6 Il problema del dizionario

Informatica 3. Informatica 3. LEZIONE 22: Politiche di risoluzione delle collisioni. Lezione 23 - Modulo 1. Politiche di risoluzione delle collisioni

Esempi. Albero di interi. Struttura che non è un albero!

ALBERI BINARI DI RICERCA

lezione 9 min-heap binario Heap e Alberi posizionali generali

Lezione 7 Alberi binari: visite e alberi di ricerca

Algoritmi e Strutture Dati

Lezione 12 Tabelle Hash

ADT Dizionario. Ordered search table. Supponiamo che sia definita una relazione d'ordine totale sulle chiavi del dizionario D:

Liste concatenate. Violetta Lonati

Algoritmi e Strutture Dati

heap heap heap? max- e min-heap concetti ed applicazioni heap = catasta condizione di heap non è una struttura ordinata

Esercizio 1. E vero che in un AVL il minimo si trova in una foglia o nel penultimo livello? FB = -1. livello 0 FB = -1. livello 1 FB = -1.

Alberi di ricerca binari

Alberi. Alberi: Esempio di utilizzo

Alberi Binari di Ricerca e Alberi Rosso-Neri

Heap e code di priorità

Algoritmi e Strutture Dati

ADT albero binario completo

Implementazione ADT: Alberi

Algoritmi e Strutture Dati

GLI ALBERI BINARI DI RICERCA. Cosimo Laneve

Informatica 3. Informatica 3. LEZIONE 13: Liste doppie, pile e code. Lezione 13 - Modulo 1. Free list (2) Free list. Free list

Il tipo astratto coda con priorità: specifiche sintattiche e semantiche. Realizzazioni.

Laboratorio di Informatica

Laboratorio di Algoritmi e Strutture Dati. Code con Priorità

Lezione 6: 12 Novembre 2013

Esercizi di Algoritmi e Strutture Dati

d. Cancellazione del valore 5 e. Inserimento del valore 1

In questa lezione Alberi binari di ricerca: la cancellazione

dizionari alberi bilanciati

Laboratorio di Algoritmi

Algoritmi e Strutture di Dati

Espressioni aritmetiche

Dipartimento di Elettronica, Informazione e Bioingegneria API 2013/4

QuickSort Università degli Studi di Milano

Implementazione dell albero binario in linguaggio C++

Albero in cui ogni nodo ha al più due figli. I figli di un nodo costituiscono una coppia ordinata

Algoritmi e Strutture dati - ANNO ACCADEMICO 2016/17 13 giugno 2017

Prova di Algoritmi e s.d. (1o anno) 7 Febbraio TESTO e RISPOSTE

Tutoraggio Informatica Generale Inserimento e cancellazione in un ABR Counting Sort

Dizionari. Dizionari con gli alberi. Alberi binari di ricerca. Realizzazione con alberi binari di ricerca. Alberi rosso-neri.

Lezione 9 Alberi binari: visite ed esercizi

Algoritmi e Strutture Dati

Struttura dati Dizionario

Alberi Binari di Ricerca

Transcript:

Informatica 3 LEZIONE 15: Implementazione di alberi binari - BST Modulo 1: Implementazione degli alberi binari Modulo 2: BST

Informatica 3 Lezione 15 - Modulo 1 Implementazione degli alberi binari

Introduzione Implementazione: alberi binari basati su puntatori discussione sullo spazio necessario alberi binary basati su array

Implementazione (1) Scelta: stessa definizione per i nodi interni e le foglie?

Implementazione (2) Esempi: albero delle espressioni, albero di Huffmann, PR quadtree,... 4x(2x+a)-c

Implementazione tramite union (1) enum Nodetype {leaf, internal}; class VarBinNode { // Generic node class public: Nodetype mytype; // Store type for node union { struct { // Internal node VarBinNode* left; // Left child VarBinNode* right; // Right child Operator opx; // Value } intl; }; Operand var; // Leaf: Value only

Implementazione tramite union (2) }; // Leaf constructor VarBinNode(const Operand& val) { mytype = leaf; var = val; } // Internal node constructor VarBinNode(const Operator& op, VarBinNode* l, VarBinNode* r) { mytype = internal; intl.opx = op; intl.left = l; intl.right = r; } bool isleaf() { return mytype == leaf; } VarBinNode* leftchild() { return intl.left; } VarBinNode* rightchild() { return intl.right; }

Implementazione tramite union (3) // Preorder traversal void traverse(varbinnode* subroot) { } if (subroot == NULL) return; if (subroot->isleaf()) cout << "Leaf: << subroot->var << "\n"; else { cout << "Internal: << subroot->intl.opx << "\n"; traverse(subroot->leftchild()); traverse(subroot->rightchild()); }

Implementazione tramite ereditarietà (1) class VarBinNode { // Abstract base class public: virtual bool isleaf() = 0; }; class LeafNode : public VarBinNode { // Leaf private: Operand var; // Operand value public: LeafNode(const Operand& val) { var = val; } // Constructor }; bool isleaf() { return true; } Operand value() { return var; }

Implementazione tramite ereditarietà (2) // Internal node class IntlNode : public VarBinNode { private: VarBinNode* left; // Left child VarBinNode* right; // Right child Operator opx; // Operator value public: IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r) { opx = op; left = l; right = r; } bool isleaf() { return false; } VarBinNode* leftchild() { return left; } VarBinNode* rightchild() { return right; } Operator value() { return opx; } };

Implementazione tramite ereditarietà (3) // Preorder traversal void traverse(varbinnode *subroot) { } if (subroot == NULL) return; // Empty if (subroot->isleaf()) // Do leaf node cout << "Leaf: " << ((LeafNode *)subroot)->value() << endl; else { // Do internal node cout << "Internal: " << ((IntlNode *)subroot)->value() << endl; traverse((intlnode *)subroot)->leftchild()); traverse(((intlnode *)subroot)->rightchild()); }

Ereditarietà - 2^ versione (1) class VarBinNode { // Abstract base class public: virtual bool isleaf() = 0; virtual void trav() = 0; }; class LeafNode : public VarBinNode { // Leaf private: Operand var; // Operand value public: LeafNode(const Operand& val) { var = val; } // Constructor bool isleaf() { return true; } Operand value() { return var; } void trav() { cout << "Leaf: " << value() << endl; } };

Ereditarietà - 2^ versione (2) class IntlNode : public VarBinNode { private: VarBinNode* lc; // Left child VarBinNode* rc; // Right child Operator opx; // Operator value public: IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r) { opx = op; lc = l; rc = r; } bool isleaf() { return false; } VarBinNode* left() { return lc; } VarBinNode* right() { return rc; } Operator value() { return opx; } void trav() { cout << "Internal: " << value() << endl; if (left()!= NULL) left()->trav(); if (right()!= NULL) right()->trav(); } };

Ereditarietà - 2^ versione (3) // Preorder traversal void traverse(varbinnode *root) { if (root!= NULL) root->trav(); }

Differenze Prima versione: semplice aggiungere nuovi metodi per l attraversamento dell albero Seconda versione: l aggiunta di nuovi metodi per l albero richiede di aggiungere dei metodi a livello di nodo Prima versione: occorre considerare sempre il tipo di nodo Seconda versione: il tipo di nodo viene determinato a tempo di esecuzione (late binding) Prima versione: preferibile se le sottoclassi dei tipi di nodi vengono tenute nascoste alla classe albero Seconda versione: preferibile se i nodi hanno anche vita indipendente

Spazio necessario (1) Overhead = spazio necessario per mantenere la struttura dati (spazio non utilizzato per memorizzare i dati) dipende da diversi fattori: nodi con stessa definizione oppure definizioni diverse per nodi interni e nodi foglia albero esteso con puntatori al padre albero pieno o non pieno

Spazio necessario (2) Esempio: n numero dei nodi p spazio occupato dal puntatore d spazio occupato dai dati Tutti i nodi sono uguali e hanno i puntatori ai figli: Spazio totale: n(2p + d) Overhead: 2pn Se p = d l overhead è pari a 2p/(2p + d) = 2/3 I nodi foglia non hanno i puntatori e l albero è pieno: n/2 (2p) p n/2 (2p) + dn p+d Se p = d l overhead è pari a 1/2 Se i dati vengono memorizzati solo nelle foglie: 2p / (2p + d) per p = d dà un overhead di 2/3

Implementazione tramite array (1) Alberi completi: Posizione 0 1 2 3 4 5 6 7 8 9 10 11 Padre 0 0 1 1 2 2 3 3 4 4 5 Figlio di sinistra 1 3 5 7 9 11 Figlio di destra 2 4 6 8 10 Fratello di sinistra 1 3 5 7 9 Fratello di destra 2 4 6 8 10

Implementazione tramite array (2) Padre (i) = (i-1) / 2 se i!= 0 Figlio di sinistra (i) = 2i + 1 se 2i + 1 < n Figlio di destra (i) = 2i + 2 se 2i + 2 < n Fratello di sinistra (i) = i - 1 se i è pari Fratello di destra (i) = i + 1 se i è dispari e i + 1 < n

Implementazione tramite cursori Alcuni linguaggi di programmazione non dispongono di puntatori Indice Dati Sinistra Destra 1 A 2 3 2 B 0 4 3 C 5 6 4 D 0 0 5 E 0 0 6 F 0 0............ MAX.........

Informatica 3 Lezione 15 - Modulo 2 Binary Search Tree (BST)

Introduzione Definizione di Binary Search Tree (BST) albero binario che soddisfa le seguenti proprietà: ad ogni nodo è associata una chiave le chiavi di tutti i nodi che si trovano nel sotto-albero di sinistra di un nodo con chiave K hanno valore inferiore a K le chiavi di tutti i nodi che si trovano nel sotto-albero di destra di un nodo con chiave K hanno valore maggiore o uguale a K

Introduzione (2) La funzione di ordinamento è gratuita : l attraversamento in ordine simmetrico ( in order ) produce come risultato l enumerazione di tutti i nodi dal più piccolo al più grande

Ricerca di un elemento Input: Radice di un sotto-albero R Chiave dell elemento da cercare K Algoritmo: Se R ha valore di chiave pari a K la ricerca è terminata (search hit) Se la chiave K è inferiore alla chiave del nodo radice R si prosegue la ricerca nel sotto-albero di sinistra Se la chiave K è maggiore della chiave del nodo radice R si prosegue la ricerca nel sotto-albero di destra Il processo continua finchè si trova la chiave oppure si arriva ad un nodo foglia Se si raggiunge un nodo foglia senza incontrare K l elemento non esiste nel BST (search miss)

Ricerca di un elemento (2) Esempio di ricerca di un elemento presente nel BST: ricerca dell elemento 7 7 è minore di 37 > visita del sotto-albero di sinistra 7 è minore di 24 > visita del sotto-albero di sinistra elemento trovato

Ricerca di un elemento (3) Esempio di ricerca di un elemento non presente nel BST: ricerca dell elemento 34 34 è minore di 37 > visita del sotto-albero di sinistra 34 è maggiore di 24 > visita del sotto-albero di destra 34 è maggiore di 32-32 è un nodo foglia > ricerca terminata: l elemento non è presente

Inserimento di un elemento L inserimento è una ricerca con esito negativo seguita dalla sostituzione del link NULL (di sinistra o di destra di un nodo esterno) con il puntatore al nodo da inserire Esempio: inserimento del nodo 34: 34 è minore di 37 > visita del sotto-albero di sinistra 34 è maggiore di 24 > visita del sotto-albero di destra 32 è un nodo foglia - 34 è maggiore di 32 > inserimento a destra 34

Inserimento di un elemento già Osservazione: presente se occorre inserire un nodo la cui chiave è già presente nel BST il nuovo elemento viene sistemato nel sotto-albero di destra del nodo già presente Un effetto collaterale di questo modo di procedere è che i nodi con chiavi replicate non sono necessariamente contigui all interno del BST Esempio: inserimento di un elemento con chiave 24 24 Per cercare tutti gli elementi con una determinata chiave si parte dal primo nodo trovato e si procede con la ricerca nel sotto-albero di destra

Cancellazione di un nodo Caso più semplice: eliminazione del nodo con chiave minima (nell esempio rimozione del nodo 5) sotto-radice Si visita l albero partendo dalla radice e continuando a scendere nel sotto-albero di sinistra fino a quando non si arriva al nodo il cui puntatore di sinistra è NULL (nodo di chiave minima) Chiamiamo questo nodo S Per rimuovere S è sufficiente fare in modo che il puntatore a sinistra del padre di S punti al figlio destro di S

Cancellazione di un nodo (2) Eliminazione di un nodo R con chiave non minima Si visita l albero partendo dalla radice fino a trovare l elemento da cancellare R Se R non ha figli allora il padre di R dovrà puntare a NULL Se R ha un figlio allora il padre di R dovrà puntare al figlio di R Se R ha due figli si può adottare il seguente approccio: si fa puntare R ad uno dei due sotto-alberi di R si applica la funzione di inserimento per tutti i nodi dell altro sotto-albero

Cancellazione di un nodo (3) Approccio alternativo: si cerca un valore in uno dei sotto-alberi che possa sostituire il valore di R (preservando le proprietà del BST) R può essere sostituito dal nodo con: la più piccola chiave maggiore del nodo rimosso la più grande chiave minore del nodo rimosso

Cancellazione di un nodo (4) Esempio di cancellazione del nodo 37 può essere sostituito dal nodo con: la più piccola chiave maggiore del nodo rimosso: 40 la più grande chiave minore del nodo rimosso: 32

Cancellazione di un nodo Osservazioni generali: Per semplificare gli algoritmi di ricerca le chiavi di ricerca sono integrate nella struttura dati Ciò richiede tipicamente un implementazione più complicata per le operazioni di cancellazione dei nodi Metodi di cancellazione alternativi: cancellazione lazy (pigra): i nodi vengono marcati con un flag come cancellati ma non vengono eliminati dalla struttura dati» gli algoritmi di ricerca devono tenere in considerazione questi flag» svantaggi: eccessive cancellazioni portano a strutture dati che sprecano spazio di memoria e tempo nella ricerca» per attenuare questi svantaggi si possono effettuare ricostruzioni periodiche della struttura oppure utilizzare i nodi cancellati per futuri inserimenti

Prestazioni dei BST I tempi di esecuzione degli algoritmi definiti sui BST dipendono dalla forma dell albero Quando l albero è perfettamente bilanciato ci sono circa log N nodi tra la radice e ciascun nodo esterno La forma dell albero dipende dall ordine con il quale gli elementi vengono inseriti Un BST di N nodi può essere costituito da una catena di nodi di altezza N Ciò accade quando gli elementi vengono inseriti ordinati 24 32 Nel caso peggiore la ricerca di un elemento in un BST con N chiavi richiede N confronti 35

Prestazioni dei BST (2) RICERCA di un elemento: Un albero bilanciato ha un costo pari a Θ(log n) nel caso medio Se l albero non è bilanciato il costo nel caso peggiore è Θ(n) INSERIMENTO di N nodi: Se l albero è bilanciato ogni inserimento richiede un costo pari a Θ(log n) > per n nodi: Θ(n log n) Se i nodi vengono inseriti in ordine (albero sbilanciato) il costo dell inserimento diventa Θ(n 2 ) VISITA DELL ALBERO: Costa Θ(n) indipendentemente dal bilanciamento dell albero

BST Search template <class Key, class Elem> bool BST<Key, Elem>:: findhelp(binnode<elem>* subroot, const Key& K, Elem& e) const { if (subroot == NULL) return false; else if (K < subroot->val()) return findhelp(subroot->left(), K, e); else if (K > subroot->val())) return findhelp(subroot->right(), K, e); else { e = subroot->val(); return true; } }

BST Insert template <class Key, class Elem> BinNode<Elem>* BST<Key,Elem>:: inserthelp(binnode<elem>* subroot, const Elem& val) { if (subroot == NULL) // Empty: create node return new BinNodePtr<Elem>(val,NULL,NULL); if (val < subroot->val()) subroot->setleft(inserthelp(subroot->left(), val)); else subroot->setright( inserthelp(subroot->right(), val)); // Return subtree with node inserted return subroot; }

Remove Minimum Value template <class Key, class Elem> BinNode<Elem>* BST<Key, Elem>:: deletemin(binnode<elem>* subroot, BinNode<Elem>*& min) { if (subroot->left() == NULL) { min = subroot; return subroot->right(); } else { // Continue left subroot->setleft( deletemin(subroot->left(), min)); return subroot; } }

BST Remove template <class Key, class Elem> BinNode<Elem>* BST<Key,Elem>:: removehelp(binnode<elem>* subroot, const Key& K, BinNode<Elem>*& t) { if (subroot == NULL) return NULL; else if (K < subroot->val()) subroot->setleft( removehelp(subroot->left(), K, t)); else if (K > subroot->val()) subroot->setright( removehelp(subroot->right(), K, t));

BST Remove (2) else { // Found it: remove it BinNode<Elem>* temp; t = subroot; if (subroot->left() == NULL) subroot = subroot->right(); else if (subroot->right() == NULL) subroot = subroot->left(); else { // Both children are non-empty subroot->setright( deletemin(subroot->right(), temp)); Elem te = subroot->val(); subroot->setval(temp->val()); temp->setval(te); t = temp; } } return subroot; }

Conclusioni I BST sono semplici da implementare e sono efficienti quando l albero è bilanciato Se non controllata questa struttura dati tende a non essere perfettamente bilanciata, portando a peggioramenti delle prestazioni Esistono strutture dati alternative (AVL tree, Splay tree, ecc.) che al prezzo di un maggiore costo per gli inserimenti e le cancellazioni cercano di mantenere bilanciato l albero