Especificación de TAD’s. TAD Pila de Enteros. Definición: Estructura de Datos que contiene una serie de elementos de tipo entero a los que sólo se puede acceder por un único lado. Característica: Primer elemento obtenido es el último introducido Estructura LIFO (Last Input, First Output) Operaciones: apilar. desapilar. pilaVacía. inicializarPila. (Gp:) desapilar
(Gp:) apilar
(Gp:) Cima de la Pila
5 3 7 2 (Gp:) Cima de la Pila
TAD Pila de Enteros: especificación (I)
* Se lanza una excepción (PilaVacia) si se intenta utilizar alguna de estas operaciones cuando la pila está vacía
Especificación de TAD’s. TAD Pila de Enteros (II)
Excepciones (I) Excepción: circunstancia que produce que una operación válida sobre un TAD no se pueda efectuar. Ejemplos: apilar: Al intentar apilar un nuevo elemento en la pila, ésta está llena. La operación apilar no debe producir ningún efecto. desapilar, cima, decapitar: Al intentar desapilar un elemento de la pila, obtener su cima o decapitarla, ésta está vacía. Estas operaciones no deben producir ningún efecto
Excepciones (II) Para especificar completa y correctamente cada operación válida de un TAD se debe indicar: Especificaciones Sintácticas. Especificaciones Semánticas. Excepciones: Se indicarán como parte de las especificaciones semánticas.
import java.io.*;
public interface Pila { boolean pilaVacia (); void eliminarPila (); int cima () throws PilaVacia; void apilar (int x); int desapilar () throws PilaVacia; void decapitar () throws PilaVacia; void imprimirPila (); void leerPila () throws NumberFormatException, IOException; int numElemPila (); } Interfaz del TAD Pila Define los métodos de objeto utilizados en la clase TadPila
Prueba (condiciones normales) import java.io.*; public class pruebaPila1 { public static void main (String [ ] args) throws PilaVacia { Pila p = new TadPila (); int x; p.apilar (1); p.apilar (2); p.apilar (3); p.apilar (11); p.apilar (15); x = p.desapilar (); System.out.println ("x = " + x); x = p.desapilar (); System.out.println ("x = " + x); p.eliminarPila (); } }
Situaciones de excepción public class pruebaPila2 { public static void main (String [] args) throws PilaVacia { Pila pila1 = new TadPila (); int i, j;
for (I = 1; I < 10; i++) pila1.apilar (i); j = pila1.desapilar (); for (I = 1; I < 10; i++) j = pila1.desapilar (); pila1.eliminarPila (); } }
Algoritmos básicos con Pilas Tratamiento recursivo. Ventaja: legibilidad. Inconveniente: consumo de memoria Justificación: Adecuación de la estructura a la técnica. Restricciones del enunciado. Mecánica: desapilar – llamar – apilar. Terminaciones: “Pesimista”: Llegar al final. Anticipada: No llamar más.
Ejemplos: Imprimir los elementos de una pila – Contar los elementos de una pila static void escribirPila (Pila pila) throws PilaVacia { int elem; if (! pila.pilaVacia ()) { elem = pila.desapilar (); System.out.println (elem); escribirPila (pila); pila.apilar (elem); } } static int contarPila (Pila pila) throws PilaVacia {
int elem, resul; if (! pila.pilaVacia ()) { elem = pila.desapilar (); resul = 1 + contarPila (pila); pila.apilar (elem); } else resul = 0; return resul; }
Obtener el duplicado de una pila static void copiarPila (Pila pilaO, Pila pilaD) throws PilaVacia { int elem; if (! pilaO.pilaVacia ()) { elem = pilaO.desapilar (); copiarPila (pilaO, pilaD); pilaO.apilar (elem); pilaD.apilar (elem); } } Ejercicio propuesto: duplicar invirtiendo el orden de los elementos en la pila copia.
Invertir el contenido de una pila Argumentos: Pila de origen y pila de destino (ambos por referencia) Fase de ida: desapilamos en pila origen y apilamos en la pila destino Fase de vuelta: apilamos en pila origen (para restablecer la pila) Fase de transición: no hacemos nada Condición de parada: pila vacía (sin terminación anticipada)
(Gp:) 5 (Gp:) 3 (Gp:) 7 (Gp:) 2
2 7 3 5 Estado inicial (Gp:) 5 (Gp:) 3 (Gp:) 7 (Gp:) 2
(Gp:) 7 (Gp:) 2
if (! pilaO.pilaVacia ()) { elem = pilaO.desapilar (); pilaD.apilar (elem); invertirPila (pilaO, pilaD); (Gp:) 3 (Gp:) 5
elem = 3 (Gp:) 7 (Gp:) 2 (Gp:) 3
(Gp:) 5
elem = 5 (Gp:) 7
2 5 elem = 2 3 7 2 5 elem = 7 3 pilaO.apilar (elem); } 7 2 3 (Gp:) 7
(Gp:) 7 (Gp:) 2 (Gp:) 5 (Gp:) 3
(Gp:) 7 (Gp:) 2
(Gp:) 7 (Gp:) 2 (Gp:) 3
5 (Gp:) 7 (Gp:) 2 (Gp:) 5 (Gp:) 3
(Gp:) 7 (Gp:) 2 (Gp:) 5 (Gp:) 3
(Gp:) 7 (Gp:) 2 (Gp:) 5 (Gp:) 3
Sumergir un elemento Consideraciones: Fase de ida: desapilamos un elemento. Condición de parada: pila.pilaVacia () (sin terminación anticipada). Transición: Apilamos el dato que queremos sumergir. Fase de vuelta: restablecemos la pila, apilando el elemento desapilado a la ida.
static void sumergir (Pila pila, int dato) throws PilaVacia { int elem; if (!pila.pilaVacia ()) { elem = pila.desapilar (); sumergir (pila, dato); pila.apilar (elem); } else pila.apilar (dato); } Sumergir un elemento
Invertir los elementos de una pila static void invertir (Pila pila) throws PilaVacia { int elem; if (!pila.pilaVacia ()) { elem = pila.desapilar (); invertir (pila); sumergir (pila, elem); } }
Página siguiente |