Partes de un Tipo Abstracto de Datos I Parte pública: Disponible para el usuario externo. I Introducción a la Computación I Primer Cuatrimestre de 2012 I Parte privada: Sólo accesible desde dentro del TAD. ¡El usuario externo nunca debe ver ni meterse en esto! I Tipos Abstractos de Datos Nombre y tipos paramétricos (ej: Lista(ELEM)). Operaciones y sus especificaciones (encabezado, precondición, poscondición). I I Estructura de representación del TAD. Invariante de representación: qué propiedades debe cumplir la estructura elegida para que tenga sentido como la representación de una instancia del TAD. Algoritmos de las operaciones para la estructura de representación elegida. 1 TAD Lista(ELEM) TAD Lista(ELEM) - Posible implementación Operaciones: I CrearLista() → Lista(ELEM) I Agregar(x, L) I Longitud(L) → Z I Iésimo(i, L) → ELEM I Cantidad(x, L) → Z I Insertar(i, x, L) I BorrarIésimo(i, L) I Indice(x, L) → Z 2 Primero elegimos una estructura de representación del TAD Lista(ELEM) (que es privada). Lista(ELEM) == hcabeza : Ref(Nodo), longitud : Zi Después describimos el invariante de representación de esta estructura. En este caso longitud siempre debe ser igual a la cantidad de nodos encadenados a partir de cabeza, y en la cadena de nodos no deben formarse ciclos. Por último, damos los algoritmos de las operaciones del TAD Lista(ELEM) para la estructura de representación elegida. donde L : Lista(ELEM), i : Z, x : ELEM (entero, char, etc.). 3 4 TAD Lista(ELEM) - Posible implementación TAD Pila(ELEM) Operaciones: Complejidad temporal de los algoritmos vistos para esta estructura de representación. I CrearPila() → Pila(ELEM): Crea una pila vacı́a. I Apilar(x, P): Inserta el elem. x sobre el tope de la pila P. I Vacı́a?(P) → B: Dice si la pila P está vacı́a. I Tope(P) → ELEM: Devuelve el elemento del tope de P. Precondición: ¬Vacı́a?(P). I Desapilar(P): Borra el elemento del tope de P. Precondición: ¬Vacı́a?(P). I CrearLista() → Lista(ELEM) I Agregar(x, L) I Longitud(L) → Z I Iésimo(i, L) → ELEM I Cantidad(x, L) → Z I Insertar(i, x, L) I BorrarIésimo(i, L) O(n) donde P : Pila(ELEM), x : ELEM (entero, char, etc.). I Indice(x, L) → Z O(n) Las pilas tienen estrategia LIFO (last in, first out). O(1) O(n) O(1) O(n) O(n) O(n) 6 5 Problema: Paréntesis balanceados TAD Pila(ELEM) - Posible implementación Dado un string, determinar si los caracteres { }, [ ], ( ) están balanceados correctamente. Estructura de representación del TAD Pila(ELEM): ¿Se les ocurre una solución usando el tipo Pila? Pila(ELEM) == hls : Listai p ← CrearPila() Para cada caracter c en el string de entrada: Si c es ‘{’, ‘[’ o ‘(’: Apilar(c, p) Si c es ‘}’, ‘]’ o ‘)’: d ← Tope(p) Desapilar(p) Si c no se corresponda con d: responder que no. Si Vacı́a?(p), responder que sı́. Si no, responder que no. Invariante de representación de esta estructura: En este caso no hay nada que decir. Según la estructura de representación elegida, cualquier lista es una representación válida de una pila. 7 8 TAD Pila(ELEM) - Posible implementación TAD Pila(ELEM) - Posible implementación Algoritmos de las operaciones del TAD Pila(ELEM) para la estructura de representación elegida: La complejidad temporal de los algoritmos vistos para esta estructura de representación dependen de la complejidad de las operaciones del TAD Lista. Suponiendo la implementación del TAD Lista que vimos, los órdenes son: CrearPila() → Pila(ELEM): RV .ls ← CrearLista() Apilar(x, P): Agregar(x, P.ls) Vacı́a?(P) → B: RV ← (Longitud(P.ls) = 0) Tope(P) → ELEM: (Pre: ¬Vacı́a?(P)) RV ← Iésimo(Longitud(P.ls) − 1, P.ls) I CrearPila() → Pila(ELEM) I Apilar(x, P) I Vacı́a?(P) → B I Tope(P) → ELEM I Desapilar(P) O(1) O(n) O(1) O(n) O(n) Desapilar(P): (Pre: ¬Vacı́a?(P)) BorrarIésimo(Longitud(P.ls) − 1, P.ls) 9 TAD Cola(ELEM) 10 TAD Conjunto(ELEM) Operaciones: Operaciones: I CrearCola() → Cola(ELEM): Crea una cola vacı́a. I Encolar(x, C ): Agrega el elemento x al final de la cola C . I CrearConjunto() → Conjunto(ELEM): Crea un conjunto vacı́o. I Vacı́a?(C ) → B: Dice si la cola C está vacı́a. I Agregar(x, C ): Agrega el elemento x al conjunto C . I Primero(C ) → ELEM: Devuelve el primer elemento de C . Precondición: ¬Vacı́a?(C ). I Pertenece?(x, C ) → B: Dice si el elemento x está en C . I Eliminar(x, C ): Elimina el elemento x de C . Desencolar(C ): Borra el primer elemento de C . Precondición: ¬Vacı́a?(C ). I Tamaño(C ) → Z: Devuelve la cantidad de elementos de C . I Iguales?(C1 , C2 ) → B: Dice si los dos conjuntos son iguales. I donde C : Cola(ELEM), x : ELEM (entero, char, etc.). donde C , C1 , C2 : Conjunto(ELEM), x : ELEM. Las pilas tienen estrategia FIFO (first in, first out). 11 12 TAD Conjunto(ELEM) TAD Conjunto(ELEM) - Posible implementación Operaciones (cont.): I Unión(C1 , C2 ) → Conjunto(ELEM): Devuelve un nuevo conjunto con C1 ∪ C2 . I Intersección(C1 , C2 ) → Conjunto(ELEM): Devuelve un nuevo conjunto con C1 ∩ C2 . I Diferencia(C1 , C2 ) → Conjunto(ELEM): Devuelve un nuevo conjunto con C1 \C2 . I ListarElementos(C ) → Lista(ELEM): Devuelve una lista de los elementos de C , en cualquier orden. I AgregarTodos(L, C ): Agrega todos los elementos de L en C . Estructura de representación del TAD Conjunto(ELEM): Conjunto(ELEM) == hls : Listai Invariante de representación de esta estructura: La lista ls no puede tener elementos repetidos. donde C , C1 , C2 : Conjunto(ELEM), x : ELEM, L : Lista(ELEM). 13 TAD Conjunto(ELEM) - Posible implementación 14 TAD Conjunto(ELEM) - Posible implementación Algoritmos de las operaciones del TAD Conjunto(ELEM) para la estructura de representación elegida: ListarElementos(C ) → Lista(ELEM): RV ← CrearLista() i ←0 while (i < Longitud(C .ls)) { Agregar(Iésimo(i, C .ls), RV ) i ←i +1 } CrearConjunto() → Conjunto(ELEM): RV .ls ← CrearLista() Agregar(x, C ): if (Cantidad(x, C .ls) = 0) Agregar(x, C .ls) Pertenece?(x, C ) → B: RV ← (Cantidad(x, C .ls) > 0) AgregarTodos(L, C ): i ←0 while (i < Longitud(L)) { Agregar(Iésimo(i, L), C ) i ←i +1 } Eliminar(x, C ): if (Cantidad(x, C .ls) > 0) BorrarIésimo(Indice(x, C .ls), C .ls) Tamaño(C ) → Z: RV ← Longitud(C .ls) 15 16 TAD Conjunto(ELEM) - Posible implementación Repaso de la clase de hoy Unión(C1 , C2 ) → Conjunto(ELEM): RV ← CrearConjunto() AgregarTodos(ListarElementos(C1 ), RV ) AgregarTodos(ListarElementos(C2 ), RV ) Iguales?(C1 , C2 ) → B: if (Tamaño(C1 ) = Tamaño(C2 )) { RV ← TRUE L ← ListarElementos(C1 ) i ←0 while (i < Longitud(L)) { RV ← RV AND Pertenece?(Iésimo(i, L), C2 ) i ←i +1 } } else { RV ← FALSE } I TAD Pila(ELEM). I TAD Cola(ELEM). I Conjunto(ELEM). Temas de las clases que vienen I Técnicas algorı́tmicas: I I 17 Backtracking. 8 reinas. Heurı́sticas. Algoritmos aproximados. 18