Alberi generici in Java Scopo della esercitazione è quello di progettare le classi necessarie ad implementare un generico albero n-ario in Java. 1 Prerequisiti Conoscenza del Java Collection Framework con particolare riferimento alle classi LinkedList<E>, ArrayList<E> e l’interfaccia Iterator<E>, con utilizzo del costrutto dei generics. Concetti e rappresentazioni di alberi n-ari. Utilizzo di interfacce e classi astratte in Java e realizzazione di classi basate su Generics 2 Rappresentazione degli alberi Per rappresentare un albero n-ario si utilizza la rappresentazione del nodo presentata a lezione: in cui ogni nodo ha un riferimento al parent (genitore), un campo element (info) che contiene un “valore” (del tipo appropriato) e una lista di riferimenti ai nodi figli. 3 Implementazione 3.1 Struttura dati di base Implementare le classi java necessarie a rappresentare il generico nodo dell’albero e poi l’intero albero sfruttando le classi di supporto fornite (pubblicate nella sezione “Laboratorio Esercitazione_3” nel sito del corso, insieme alle relative API). 1 In particolare realizzare la classe TreeNode<E> che implementa l’interfaccia Position<E> e che rappresenta il generico nodo dell’albero. Per la progettazione di tale classe ispirarsi allo schema riportato nella sezione 2. Realizzare poi una classe MyTree<E> che implementa l’interfaccia Tree<E> che rappresenta un albero generico, basandosi sulla classe TreeNode per la modellazione dei nodi dell’albero. Realizzare una classe MyTest con un main per il test della rappresentazione. In particolare creare un albero, inserire alcuni valori di prova nell’albero e poi stamparlo con il metodo stampa della classe TreeUtil. Un possibile esempio di test è il seguente: 1. MyTree<Integer> t = new MyTree<Integer>(); 2. Position<Integer> root = t.setRoot(100); 3. Position<Integer> c = root.addChildren(20); 4. final Position<Integer> child = root.addChildren(230); 5. child.addChildren(1); 6. child.addChildren(2); 7. child.addChildren(3); 8. c.addChildren(4); 9. TreeUtil.stampa(t); 3.2 Metodi di IO Realizzare nella classe TreeUtil i seguenti metodi che permettono l’importazione/esportazione di alberi in notazione parentetica: 1. public static <E> void printParentheticalRepresentation (Tree<E> tree) stampa l’albero secondo la rappresentazione parentetica 2. public static Tree<String> parseParentheticalRepresentation (String rappParentetica) a partire dalla rappresentazione parentetica costruisce l’albero corrispondente La rappresentazione parentetica di un albero è definita nel seguente modo: <albero> = ( <radice> <sottoalbero1><sottoalbero2>.... (<sottoalberon> ) Esempio Dato l’albero 2 a b c d e g f la sua rappresentazione parentetica è: (a(b(c)(d)(g))(e(f))) 3.3 Metodi avanzati Aggiungere alla interfaccia Tree<E> e alla corrispondente classe MyTree<E> i seguenti metodi: 1. public int size() a. ritorna il numero di nodi dell’albero 2. public void preorder() a. stampa in output i nodi dell’albero in preordine 3. public int depth () a. ritorna la profondità dell’albero 3.4 Approfondimenti Implementare la classe MyTree2<E> e TreeNode2<E> che sfruttino la rappresentazione dei nodi come firstChild (primo figlio), nextSibling (fratello) presentata a lezione. 3