Estructuras de Datos Tema 1. Introducción Tema 2. Análisis de Algoritmos Tema 3. Listas Tema 4. Pilas y Colas Tema 5. Árboles Tema 6. TDAs ordenados Tema 7. Mapas Tema 8. Conjuntos, Bolsas y Listas sin repetición Tema 9. Grafos Estructuras de Datos © M. Aldea Oct-13 1 Tema 4. Pilas y Colas Tema 4. Pilas y Colas 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 4.7. 4.8. 4.9. TDA Pila Implementación de Pilas basada en array Implementación de Pilas basada en celdas enlazadas TDA Cola Implementación de Colas basada en array circular Implementación de Colas basada en celdas enlazadas Comparación de las implementaciones Pilas y Colas en “Java Collections Framework” Bibliografía Estructuras de Datos © M. Aldea Oct-13 2 Tema 4. Pilas y Colas Objetivos • Conocer los TDAs Pila y Cola • Conocer las técnicas básicas de implementación de Pilas y Colas: basadas en array y basadas en estructuras enlazadas • Conocer las ventajas e inconvenientes de las distintas técnicas de implementación de acuerdo a su complejidad espacial y temporal • Conocer el soporte proporcionado para Pilas y Colas en las “Java Collections” • Saber elegir el TDA Pila o Cola y su implementación que mejor satisfaga los requisitos de una aplicación Estructuras de Datos © M. Aldea Oct-13 3 Tema 4. Pilas y Colas 4.1 TDA Pila 4.1 TDA Pila Colección de elementos potencialmente repetidos donde la posición de cada elemento es relevante y las inserciones y eliminaciones sólo se pueden realizar en una posición denominada “cima” • Es decir, los elementos se añaden y extraen en orden LIFO (last-in-first-out, el último en entrar es el primero en salir) cima cima cima D C B A apila(E) E D C B A F E D C B A apila(F) cima E D C B A desapila() © M. Aldea Oct-13 Estructuras de Datos 4 Tema 4. Pilas y Colas 4.1 TDA Pila Operaciones de las pilas // añade el elemento en la cima de la pila apila(e: Elemento) // elimina y retorna el elemento que ocupaba la // la cima. La cima pasa al siguiente elemento desapila(): Elemento // retorna (pero no elimina) el elemento que // ocupa la cima. La cima no cambia. cima(): Elemento // vacía la pila (pasa a tener tamaño 0) haceVacía() // retorna el tamaño de la pila (num. elementos) tamaño(): Entero // indica si la pila está vacía estáVacía(): Booleano © M. Aldea Oct-13 Estructuras de Datos 5 Tema 4. Pilas y Colas 4.1 TDA Pila Implementaciones de pilas E <<interface>> Pila +apila(e: E) +desapila(): E +cima(): E +haceVacía(): void +tamaño(): Entero +estáVacía(): Bool E PilaArray Estructuras de Datos E PilaSimpleEnlace © M. Aldea Oct-13 6 Tema 4. Pilas y Colas 4.1 TDA Pila Uso de pilas Pila de platos para fregar -platos PlatosParaFregar Plato * <<PilaArray>> {ordered, nonunique} +dejaPlato(p: Plato) +cogePlato():Plato Pila de operaciones de edición para implementar el “deshacer” de un editor de texto OperacionesDeEdición <<PilaSimpleEnlace>> +registraOp(Op: OperaciónDeEdición) +últimaOp(): OperaciónDeEdición * {ordered, nonunique} -operaciones OperaciónDeEdición © M. Aldea Oct-13 Estructuras de Datos 7 Tema 4. Pilas y Colas 4.2 Implementación de Pilas basada en array 4.2 Implementación de Pilas basada en array Array de elementos y cursor que indica la cima de la pila • cuando la pila está vacía cima=-1 elementos : Elemento[N] cima : Entero N-1 ... cima=c parte libre c+1 c c-1 Elemento más nuevo Segundo elemento más nuevo ... parte ocupada Segundo elemento más viejo Elemento más viejo 1 0 elementos Estructuras de Datos © M. Aldea Oct-13 8 Tema 4. Pilas y Colas 4.2 Implementación de Pilas basada en array Implementación de Pilas basada en array (cont.) procedimiento apila(e: Elemento) si tamaño() = N entonces error // no caben más elementos fsi cima := cima + 1 elementos[cima] := e fprocedimiento procedimiento desapila(): Elemento si estáVacía() entonces error // no hay elementos fsi cima := cima - 1 retorna elementos[cima+1] fprocedimiento Estructuras de Datos © M. Aldea Oct-13 9 Tema 4. Pilas y Colas 4.2 Implementación de Pilas basada en array Implementación de Pilas basada en array (cont.) procedimiento haceVacía() cima := -1 fprocedimiento procedimiento tamaño(): Entero retorna cima + 1 fprocedimiento procedimiento estáVacía(): Booleano retorna cima = -1 fprocedimiento procedimiento cima(): Elemento si estáVacía() entonces error fsi retorna elementos[cima] fprocedimiento © M. Aldea Oct-13 Estructuras de Datos 10 Tema 4. Pilas y Colas 4.3 Implementación de Pilas basada en celdas enlazadas 4.3 Implementación de Pilas basada en celdas enlazadas Implementación directa y eficiente (O(1)) utilizando celdas simplemente enlazadas • inserciones y extracciones por la cabeza de la lista de celdas c cima b a apila(d) d cima c b a desapila() retorna d c cima b a © M. Aldea Oct-13 Estructuras de Datos 11 Tema 4. Pilas y Colas 4.4 TDA Cola 4.4 TDA Cola Colección de elementos potencialmente repetidos donde la posición de cada elemento es relevante, las inserciones sólo se pueden realizar por el “final” y las eliminaciones por el “frente” • Es decir, los elementos se añaden y extraen en orden FIFO (first-in-first-out, el primero en entrar es el primero en salir) a b c d frente final encola(e) a b c d e frente final desencola() retorna a b frente Estructuras de Datos c d e final © M. Aldea Oct-13 12 Tema 4. Pilas y Colas 4.4 TDA Cola Operaciones de las colas // añade el elemento al final de la cola encola(e: Elemento) // elimina y retorna el elemento que ocupaba el // frente. El siguiente elemento pasa al frente desencola(): Elemento // retorna (pero no elimina) el elemento que // ocupa el frente. El frente no cambia. frente(): Elemento // vacía la cola (pasa a tener tamaño 0) haceVacía() // retorna el tamaño de la cola (num. elementos) tamaño(): Entero // indica si la cola está vacía estáVacía(): Booleano © M. Aldea Oct-13 Estructuras de Datos 13 Tema 4. Pilas y Colas 4.4 TDA Cola Implementaciones de colas E <<interface>> Cola +encola(e: E) +desencola(): E +frente(): E +haceVacía(): void +tamaño(): Entero +estáVacía(): Bool E E ColaArray ColaSimpleEnlace © M. Aldea Oct-13 Estructuras de Datos 14 Tema 4. Pilas y Colas 4.4 TDA Cola Uso de colas Cola de la caja de un supermercado -clientes ClientesCaja Cliente * <<ColaArray>> {ordered} Cola de trabajos pendientes en una impresora -trabajos TrabajosPendientes TrabajoImpresión * <<ColaSimpleEnlace>> {ordered, nonunique} Estructuras de Datos © M. Aldea Oct-13 15 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular 4.5 Implementación de Colas basada en array circular Array de elementos y dos cursores que indican el frente y el final • “array circular”: cuando un cursor sobrepasa la última posición del array, vuelve a la primera elementos : Elemento[N] frente, final : Entero Ejemplo. Dos configuraciones de cola válidas: 0 1 2 3 4 5 6 7 8 9 10 a b c d e frente=6 11 12 13 14 15 final=10 0 1 2 3 k l m n 4 5 6 7 8 9 10 final=3 11 12 13 14 15 i j frente=14 © M. Aldea Oct-13 Estructuras de Datos 16 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Implementación de Colas basada en array circular (cont.) 1 0 2 3 4 5 6 b a encola(c) frente final 0 1 b c 1 b c 2 3 4 5 3 4 5 6 a final desencola()a 0 2 frente 6 desencola()b final 0 frente 1 2 2 3 4 5 6 c desencola()c 0 1 3 4 5 final frente 6 frente final © M. Aldea Oct-13 Estructuras de Datos 17 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Detección de cola vacía/llena Hay dos opciones: • Llevando un contador con el número de elementos -Necesidad de una variable extra (el contador) +Se puede llenar el array totalmente • Utilizando la posición relativa de los cursores +No hace falta ninguna variable extra -Siempre debe quedar, al menos, una posición libre en el array Son soluciones equivalentes • no hay un acuerdo general sobre cual es mejor • unas implementaciones/libros eligen una y otros otra Estructuras de Datos © M. Aldea Oct-13 18 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Detección de cola vacía/llena con los cursores Vacía cuando frente está en la posición siguiente a final 0 1 2 3 4 5 (final + 1) mod N = frente 6 frente final Problema: en una cola totalmente llena también se cumple que frente está en la posición siguiente a final • Solución: no se permite llenar la cola del todo 0 1 2 3 4 5 6 0 1 e f g a b c d e f final frente 2 3 4 5 6 a b c d frente final Llena cuando frente está dos posiciones por delante de final (final + 2) mod N = frente Tamaño de la cola: (N - frente + final + 1) mod N © M. Aldea Oct-13 Estructuras de Datos 19 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Implementación con contador de elementos procedimiento haceVacía() tamaño := 0 frente := 0 final := N - 1 fprocedimiento 0 1 2 3 4 5 6 frente tamaño=0 final procedimiento tamaño(): Entero retorna tamaño fprocedimiento procedimiento estáVacía(): Booleano retorna tamaño = 0 fprocedimiento Estructuras de Datos © M. Aldea Oct-13 20 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Implementación con contador de elementos (cont.) procedimiento frente(): Elemento si estáVacía() entonces error fsi retorna elementos[frente] fprocedimiento procedimiento desencola(): Elemento si estáVacía() entonces error fsi tamaño := tamaño - 1 Elemento temp := elementos[frente] frente := (frente + 1) mod N retorna temp fprocedimiento Estructuras de Datos © M. Aldea Oct-13 21 Tema 4. Pilas y Colas 4.5 Implementación de Colas basada en array circular Implementación con contador de elementos (cont.) procedimiento encola(e: Elemento) si tamaño() = N entonces error fsi tamaño := tamaño + 1 final := (final + 1) mod N elementos[final] := e fprocedimiento mod: operador módulo (en Java es el operador “%”) • resto de la división entera 7 mod 4 = 3 18 mod 9 = 0 0 mod 4 = 0 © M. Aldea Oct-13 Estructuras de Datos 22 Tema 4. Pilas y Colas 4.6 Implementación de Colas basada en celdas enlazadas 4.6 Implementación de Colas basada en celdas enlazadas Implementación directa y eficiente utilizando celdas simplemente enlazadas • inserciones por el final y extracciones por el principio de la lista final a frente b c encola(d) frente a final b c d desencola() a final frente b c d © M. Aldea Oct-13 Estructuras de Datos 23 Tema 4. Pilas y Colas 4.6 Implementación de Colas basada en celdas enlazadas Implementación de Colas basada en celdas enlazadas (cont.) Implementación con celda de cabecera tipo Celda contenido : puntero a Elemento siguiente : puntero a Celda ftipo frente : puntero a Celda final : puntero a Celda numEle : Entero procedimiento Constructor numEle := 0 frente := nueva Celda frente.siguiente := null final := frente fprocedimiento Estructuras de Datos final null frente © M. Aldea Oct-13 24 Tema 4. Pilas y Colas 4.6 Implementación de Colas basada en celdas enlazadas Implementación de Colas basada en celdas enlazadas (cont.) procedimiento encola(e : Elemento) nuevaCelda : puntero a Celda := nueva Celda nuevaCelda.contenido := e final a numEle++ final.siguiente := nuevaCelda final := nuevaCelda fprocedimiento frente encola(z) final a z a b frente procedimiento desencola(): Elemento si estáVacía() entonces error fsi frente numEle-frente := frente.siguiente retorna frente.contenido fprocedimiento final desencola() final a b frente © M. Aldea Oct-13 Estructuras de Datos 25 Tema 4. Pilas y Colas 4.6 Implementación de Colas basada en celdas enlazadas Implementación de Colas basada en celdas enlazadas (cont.) procedimiento frente(): Elemento si estáVacía() entonces error fsi retorna frente.siguiente.contenido fprocedimiento procedimiento estáVacía(): Boolean retorna numEle = 0 fprocedimiento final a procedimiento haceVacía() numEle := 0 frente := final fprocedimiento b frente haceVacía() final a b frente © M. Aldea Oct-13 Estructuras de Datos 26 Tema 4. Pilas y Colas 4.7 Comparación de las implementaciones 4.7 Comparación de las implementaciones Eficiencia temporal de las operaciones: Operación pila/cola Array y Lista enlazada apila/encola O(1) desapila/desencola O(1) cima/frente O(1) tamaño O(1) haceVacía O(1) estáVacía O(1) Es algo más rápida la implementación basada en array Estructuras de Datos © M. Aldea Oct-13 27 Tema 4. Pilas y Colas 4.7 Comparación de las implementaciones Comparación de las implementaciones (cont.) Características generales: Característica Array Lista Enlazada Requisitos de memoria O(N), donde N es el tamaño del array de elementos O(n), donde n es el número de elementos en la pila Fácil crecimiento No, requiere redimensionado y copia Sí, puesto que no está acotada Aprovechamiento de la memoria Desperdicia memoria Usa la memoria justa En general la implementación con array es más sencilla y eficiente • debería usarse siempre que se tenga bien acotada la longitud máxima que puede alcanzar la pila/cola © M. Aldea Oct-13 Estructuras de Datos 28 Tema 4. Pilas y Colas 4.8 Pilas y Colas en “Java Collections Framework” 4.8 Pilas y Colas en “Java Collections Framework” E <<interface>> Iterable E <<interface>> Collection Cola JCF NO incluye la interfaz Stack (Pila) E <<interface>> Queue Pila E LinkedList © M. Aldea Oct-13 Estructuras de Datos 29 Tema 4. Pilas y Colas 4.8 Pilas y Colas en “Java Collections Framework” Pilas en JCF JFC no incluye ninguna interfaz específica para las pilas Utilizaremos LinkedList -platos PlatosParaFregar Plato * <<LinkedList>> +dejaPlato(p: Plato) +cogePlato():Plato {ordered, nonunique} public class PlatosParaFregar { private LinkedList<Plato> platos = new LinkedList<Plato>(); ... Estructuras de Datos © M. Aldea Oct-13 30 Tema 4. Pilas y Colas 4.8 Pilas y Colas en “Java Collections Framework” Pilas en JCF (cont.) De la clase LinkedList usaremos los métodos: void addFirst(E e); // apila E removeFirst(); // desapila // si cola vacía: lanza excepción E getFirst(); // cima // si cola vacía: lanza excepción void clear(); // haceVacía int size(); // tamaño boolean isEmpty(); // estáVacía © M. Aldea Oct-13 Estructuras de Datos 31 Tema 4. Pilas y Colas 4.8 Pilas y Colas en “Java Collections Framework” Colas en JCF Interfaz Queue, utilizando su implementación LinkedList -trabajos TrabajosPendientes TrabajoImpresión * <<LinkedList>> {ordered, nonunique} public class TrabajosPendientes { private Queue<TrabajoImpresión> trabajos = new LinkedList<TabajoImpresión>(); ... Estructuras de Datos © M. Aldea Oct-13 32 Tema 4. Pilas y Colas 4.8 Pilas y Colas en “Java Collections Framework” Colas en JCF (cont.) public interface Queue<E> extends Collection<E> { // encola boolean offer(E e);// si cola llena: retorna false boolean add(E e);// si cola llena: lanza excepción // frente E peek(); // si cola vacía: retorna null E element(); // si cola vacía: lanza excepción // desencola E poll(); // si cola vacía: retorna null E remove(); // si cola vacía: lanza excepción } Además, de Collection hereda los métodos: void clear(); // haceVacía int size(); // tamaño boolean isEmpty(); // estáVacía Estructuras de Datos © M. Aldea Oct-13 33 Tema 4. Pilas y Colas 4.9 Bibliografía 4.9 Bibliografía [1] Michael T. Goodrich, Roberto Tamassia, Data structures and algorithms in Java. John Wiley & Sons, 2006. [2] Aho A.V., Hopcroft J.E., Ullman J.D., Estructuras de datos y algoritmos. Addison-Wesley, 1988. [3] Weiss, Mark Allen, Data Structures and Algorithm Analysis in Java. Pearson Education, 2007. [4] Weiss, Mark Allen, Estructuras de datos y algoritmos. Addison-Wesley Iberoamericana, 1995. [5] Sahni, Sartaj, Data structures, algorithms, and applications in Java. McGraw Hill, 2000 [6] The Java Tutorials: Collections http://docs.oracle.com/javase/tutorial/collections/index.html Estructuras de Datos © M. Aldea Oct-13 34