4/18/2016 Estructuras de Datos Dr. Sergio A. Gómez Representaciones de árboles Estructuras de Datos Clase 9 – Árboles Generales (segunda parte) • Del padre • Lista de hijos • Goodrich & Tamassia: Del padre + Lista de hijos • Hijo extremo izquierdo – hermano derecho • Variantes de las de más arriba usando arreglos con cursores (sólo de interés histórico) Dr. Sergio A. Gómez http://cs.uns.edu.ar/~sag Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur Bahía Blanca, Argentina Estructuras de datos - Dr. Sergio A. Gómez Representación del padre Representación de lista de hijos • Cada nodo conoce su rótulo y a su padre. A C B • Cada nodo conoce su rótulo (elemento) y la lista de sus nodos hijos • El árbol conoce el nodo raíz del árbol A D B C 2 D E E Arbol<E> • Aplicación: Directorio padre en sistemas de archivos • El directorio padre se denota con .. (dos puntos consecutivos). raiz: Nodo<E> size: integer Nodo<E> elem: E hijos: Lista<Nodo<E>> Referenciav al directorio padre El directorio corriente es c:\windows El comando cd.. lleva al directorio padre. Estructuras de datos - Dr. Sergio A. Gómez 3 Estructuras de datos - Dr. Sergio A. Gómez Representación de lista de hijos a Representación en GT: Colección de hijos • GT = Lista de hijos + padre • El árbol conoce la raíz • Cada nodo conoce el rótulo (elemento), la lista de nodos hijos y el nodo padre. :Nodo<Character> A :Arbol<Character> [ , , ] 5 :Nodo<Character> B A B C D [ ] E :Nodo<Character> E 4 :Nodo<Character> C [] :Nodo<Character> D [] [] Estructuras de datos - Dr. Sergio A. Gómez 5 Estructuras de datos - Dr. Sergio A. Gómez 6 El uso total o parcial de este material está permitido siempre que se haga mención explícita de su fuente: “Estructuras de Datos. Notas de Clase”. Sergio A. Gómez. Universidad Nacional del Sur. (c) 2013-2016. Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur 1 4/18/2016 Estructuras de Datos Dr. Sergio A. Gómez Representación de árboles en GT Representación en GT public class Nodo<E> implements Position<E> { private E elemento; private Nodo<E> padre; private PositionList<Nodo<E>> hijos; Iterable<E> Position<E> public Nodo( E elemento, Nodo<E> padre ) { this.elemento = elemento; this.padre = padre; hijos = new MiLista<Nodo<E>>(); } public Nodo(E elemento ) { this( elemento, null); } public E element() { return elemento; } public PositionList<Nodo<E>> getHijos() { return hijos; } public void setElemento( E elemento ) { this.elemento = elemento; } public Nodo<E> getPadre() { return padre; } public void setPadre( Nodo<E> padre ) { this.padre = padre; } Tree<E> Nodo<E> Arbol<E> elem: E padre: Nodo<E> hijos: Lista<Nodo<E>> raiz: Nodo<E> size: integer } Estructuras de datos - Dr. Sergio A. Gómez 7 Representación en GT public Position<E> addFirstChild(Position<E> p, E e) throws InvalidPositionException { Nodo<E> padre = checkPosition(p); Nodo<E> nodo = new Nodo<E>( e, padre ); padre.getHijos().addFirst( nodo ); size++; return nodo; } public Arbol() { raiz = null; size = 0; } public boolean isEmpty() { return raiz == null; } public void createRoot( E e ) throws InvalidOperationException { if( !isEmpty() ) throw new InvalidOperationException( “Arbol no vacío” ); raiz = new Nodo<E>( e ); size = 1; } public Position<E> addBefore(Position<E> p, Position<E> rb, E e) throws InvalidPositionException { Nodo<E> padre = checkPosition( p ); Nodo<E> hermanoDerecho = checkPosition( rb ); Nodo<E> nuevo = Nodo<E>( e, padre ); PositionList<Nodo<E>> hijosPadre = padre.getHijos(); boolean encontreUbicacion = false; Position<Nodo<E>> posHijosPadre = hijosPadre.first(); while( posHijosPadre != null && !encontreUbicacion ) if( hermanoDerecho != posHijosPadre.element() ) posHijosPadre = posHijosPadre != hijosPadre.last() ? hijosPadre.next(posHijos) : null; else encontreUbicacion = true; if( !encontreUbicacion ) throw new InvalidPositionException( “rb no es hijo de p” ); hijosPadre.addBefore( posHijosPadre, nuevo ); size++; return nuevo; } Estructuras de datos - Dr. Sergio A. Gómez 8 public boolean isExternal(Position<E> v) throws InvalidPositionException { Nodo<E> nodo = checkPosition( v ); return nodo.getHijos().isEmpty(); } public class Arbol<E> implements Tree<E> { protected Nodo<E> raiz; protected int size; public Position<E> root() throws EmptyTreeException { if( isEmpty() ) throw new EmptyTreeException( “Árbol vacío” ); return raiz; } Estructuras de datos - Dr. Sergio A. Gómez Estructuras de datos - Dr. Sergio A. Gómez 9 11 Estructuras de datos - Dr. Sergio A. Gómez 10 public void removeExternalNode (Position<E> p) throws InvalidPositionException { if( isEmpty() ) throw new InvalidPositionException( “Arbol vacío” ); Nodo<E> n = checkPosition( p ); if( !n.getHijos().isEmpty() ) throw new InvalidPositionException( “p no es hoja” ); Nodo<E> padre = n.getParent(); PositionList<Nodo<E>> hijosPadre = padre.getHijos(); boolean encontre = false; Position<Nodo<E>> pos = hijosPadre.first(); while( pos != null && !encontre ) if( pos.element() == n ) encontre = true; else pos = hijosPadre.last() != pos ? hijosPadre.next( pos ) : null; if( pos == null ) throw new InvalidPositionException( “p no aparece en la lista de” + “hijos de su padre--- árbol corrupto???” ); hijosPadre.remove( pos ); size--; } Estructuras de datos - Dr. Sergio A. Gómez 12 El uso total o parcial de este material está permitido siempre que se haga mención explícita de su fuente: “Estructuras de Datos. Notas de Clase”. Sergio A. Gómez. Universidad Nacional del Sur. (c) 2013-2016. Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur 2 4/18/2016 Estructuras de Datos Dr. Sergio A. Gómez Árboles generales: Iterador Árboles generales: children public Iterable<Position<E>> positions() { PositionList<Position<E>> l = new MiLista<Position<E>>(); if( !isEmpty() ) pre( l, raiz ); return l; } // Tpositions(n) = O(n) si árbol this tiene n nodos public Iterable<Position<E>> children( Position<E> v ) throws InvalidPositionException { if( v == null ) throw new InvalidPositionException( "Children: Posición inválida"); Nodo<E> p = checkPosition(v); private void pre(PositionList<Position<E>> l, Nodo<E> r) { l.addLast( r ); for( Nodo<E> h : r.getHijos()) pre( l, h ); } El tiempo de ejecución es lineal en la cantidad de nodos del árbol PositionList<Position<E>> lista = new MiLista<Nodo<E>>(); for( Nodo<E> n : p.getHijos() ) lista.addLast(n); return lista; } El tiempo de ejecución es del orden de la cantidad de hijos de v Estructuras de datos - Dr. Sergio A. Gómez 13 public Iterator<E> iterator() { // Titerator(n) = O(n) si árbol this tiene n nodos PositionList<E> l = new MiLista<E>(); for( Position<E> p : positions() ) l.addLast( p.element() ); return l.iterator(); // Alternativa: new ElementIterator<E>( l ); Estructuras de datos - Dr. Sergio A. Gómez } Representación HEI-HD Representaciones con arreglos Cada nodo conoce su rótulo y la identidad de su hijo extremo izquierdo y de su hermano derecho (se puede combinar con la representación del padre de ser necesario) A Nodo<E> Arbol<E> B elem: E HEI, HD : Nodo<E> raiz: Nodo<E> size: integer nodos padres A C D B C C D E A B 14 D 0 1 2 3 4 A B C D E -1 HEI 1 0 4 HD -1 size 5 raiz 0 2 0 0 1 -1 -1 -1 3 -1 5 ….. -1 E E Estructuras de datos - Dr. Sergio A. Gómez 15 Estructuras de datos - Dr. Sergio A. Gómez 16 El uso total o parcial de este material está permitido siempre que se haga mención explícita de su fuente: “Estructuras de Datos. Notas de Clase”. Sergio A. Gómez. Universidad Nacional del Sur. (c) 2013-2016. Departamento de Ciencias e Ingeniería de la Computación Universidad Nacional del Sur 3