Estructuras de Datos Conjunto de nodos sobre los cuales existe una relación de paternidad que verifica: ◦ Si no es vacío tiene un único nodo distinguido llamado raíz, que no tiene padre. ◦ Cada nodo que no es raíz tiene un único padre. 1 Modelo: Árbol con nodos rotulados ordenado de izquierda a derecha. y Las operaciones de TDAArbol se definen en función de posiciones. No se definen en función de sus nodos para: ◦ No exponer la implementación. ◦ No permitir cambios en la estructura (solo se puede modificar el estado interno a través de las operaciones del TDA). La interfaz GTTree es la que se propone en el libro Data Structures and Algorithms in java. Es una interfaz que solamente tiene un método para modificar la estructura. La interfaz Tree es una interfaz creada por la cátedra de ED en la que se brindan diferentes operaciones para modificar la estructura del árbol. 2 Public interface GTTree<E> extends iterable<E> { public int size(); public boolean isEmpty(); public Iterator<E> iterator(); public Iterable<Position<E>> positions(); public E replace(Position<E> v, E e) throws InvalidPositionException; public Position<E> root() throws EmptyTreeException; public Position<E> parent(Position<E> v) throws InvalidPositionException, BoundaryViolationException; public Iterable<Position<E>> children(Position<E> v) throws InvalidPositionException; …. public boolean isInternal(Position<E> v) throws InvalidPositionException; public boolean isExternal(Position<E> v) throws InvalidPositionException; public boolean isRoot(Position<E> v) throws InvalidPositionException; } 3 Incluye todos los servicios de la interfaz tree y ademas: public interface Tree<E> extends Iterable<E>{ … public void createRoot(E e) throws InvalidOperationException; public Position<E> addFirstChild(Position<E> p, E e) throws InvalidPositionException; public Position<E> addLastChild(Position<E> p, E e) throws InvalidPositionException; public Position<E> addBefore(Position<E> p, Position<E> rb, E e) throws InvalidPositionException; public Position<E> addAfter(Position<E> p, Position<E> lb, E e) throws InvalidPositionException; public void removeExternalNode(Position<E> p) throws InvalidPositionException; public void removeInternalNode(Position<E> p) throws InvalidPositionException; public void removeNode(Position<E> p) throws InvalidPositionException; } 4 Una alternativa consiste utilizar una estructura de colección de hijos y enlace al padre. Padre Hijos E … Interface Position<E> public class TNodo<E> implements Position<E> { protected E elemento; protected TNodo<E> padre; protected PositionList<TNodo<E>> hijos; E element() Class TNodo<E> public TNodo(E el, TNodo<E> p) { element=el; padre=p; hijos= new Lista<TNodo<E>>(); } public TNnode<E> padre() {/*completar.*/} public PositionList<TNodo<E>> Hijos() {/*completar.*/} public void setPadre (TNodo<E> p) {/*completar.*/}} etc….. 5 Padre Hijos a a b Padre Hijos Padre b Hijos Padre Hijos e Interface Tree<E> c Padre Hijos Padre Hijos c d e f d f Padre Hijos Raíz a Tamaño Padre Hijos Padre b Hijos c Padre Hijos d Class Arbol<E> Padre Hijos e Padre Hijos f 6 Interface Tree<E> public class Arbol<E> implements Tree<E> { protected TNodo<E> root; protected int size; public Arbol() { root=null; size=0; } public int size() {return size;} Class Arbol<E> public Position<E> root() {return root;} public boolean isEmpty() {return size==0;} etc….. Que la posición no sea nula. Que se pueda hacer el cast a un objeto de tipo TNodo<E>. protected TNode<E> checkPosition (Position<E> v) throws InvalidPositionException; {TNodo<E> nodo=null; if (v==null) throw new InvalidPositionException(“Posicion Invalida”); try{ nodo= (TNodo<E>) v; }catch (ClassCastException e) {throw new InvalidPositionException(“Posicion Invalida”);} return nodo; } 7 public class Arbol<E> { implements Tree<E> public E replace (Position<E> v, E e) throws InvalidPositionException; { TNode<E> nodo= checkPosition(v); E toReturn=nodo.element(); nodo.setElement(e); return (toReturn); } public Position<E> parent(Position<E> v) throws InvalidPositionException, BoundaryViolationException; { TNode<E> nodo= checkPosition(v); if (nodo==root) throw new BoundaryViolationException(); return nodo.getPadre(); } Interface Iterable<E> Iterator<E> iterator() Interface Iterator<E> boolean hasNext() E next() Interface Tree<E> Class ElementIterator<E> Class Arbol<E> 8 public class Arbol<E> implements Tree<E> { … public Iterator<E> iterator() { PositionList<E> list= new Lista<E>(); if (size>0) recPreorden(root, list); return (new ElementIterator(list)); // alternativa return list.iterator(); } } Implementación de un recorrido en odern previo: Private void recPreorden(TNode<E> r, PositionList<E> l){ l.addLast(r.element()); for(TNode<E> p: r.hijos()) recPreorden(p,l); } 9 public class Arbol<E> implements Tree<E> { … public Iterable<Position<E>> positions() { PositionList<Positions<E>> list= new Lista<Positions<E>>(); if (size>0) RecPosorden(root, list); return (list); } } Implementación de un recorrido en odrden posterior: Private void recPosorden(TNode<E> r, PositionList<E> l){ for(TNode<E> p: r.hijos()) recPosorden(p,l); l.addLast(r)); } 10 Interface Iterator<E> Interface Iterable<E> ElementIterator <E> Interface Positon<E> Interface PositionList<E> Interface Tree<E> Class TNodo<E> Class Nodo<E> 1 Class Arbol<E> Clase Lista<E> ¿Preguntas? 11