Está en la página 1de 35

Tema 2 Tipos abstractos de datos.

2.2 Pila de nmeros enteros


Especificacin de TADs. TAD Pila de Enteros.

 Definicin: Estructura de Datos que


desapilar apilar
contiene una serie de elementos de tipo
entero a los que slo se puede acceder
por un nico lado.
 Caracterstica: Primer elemento
obtenido es el ltimo introducido
 Estructura LIFO (Last input, First
2
Output)
7  Operaciones:
Cima de
la Pila  apilar.
3 Cima de  desapilar.
la Pila  pilaVaca.
5  inicializarPila.
TAD Pila de Enteros: especificacin (I)

Operacin Especificacin semntica Especificacin sintctica

inicializarPila Mtodo que deja a disposicin del void inicializarPila ()


programa un TAD pila sobre el que se
podr operar posteriormente.
(Equivalente a crear o construir un
objeto/instancia.).
apilar * Mtodo que entrega un elemento (x) void apilar (int x)
para que quede incorporado en la cima
de la pila.
desapilar * Mtodo que elimina el elemento que int desapilar ()
ocupa la cima de la pila y devuelve
como resultado dicho elemento.
pilaVacia Mtodo que al ejecutarse devuelve true boolean pilaVacia ()
si la pila est vaca (no tiene
elementos), y false en caso contrario.
cima * Mtodo que devuelve la cima de la pila int cima ()
(sin alterarla).
decapitar * Mtodo que elimina el elemento de la void decapitar ()
cima de la pila.
Especificacin de TADs. TAD Pila de Enteros (II)

Operacin Especificacin semntica Especificacin sintctica

leerPila Mtodo que se utiliza para realizar la carga void leerPila () throws
inicial de elementos de la pila. NumberFormatException,
IOException

imprimirPila Mtodo que muestra en la pantalla el void imprimirPila ()


contenido de la pila.

eliminar Mtodo que recibe una pila (que puede void eliminarPila ()
tener elementos o no) y la devuelve vaca.
numElemPila Mtodo que devuelve el nmero de int numElemPila ()
elementos de la pila.
Excepciones (I)

 Excepcin: circunstancia que produce que una


Operacin Vlida sobre un TAD no pueda ser efectuada.
 Ejemplos:
 apilar:
 Al intentar apilar un nuevo elemento en la pila, sta est llena.
La operacin apilar no debe producir ningn efecto.
 desapilar, cima, decapitar:
 Al intentar desapilar un elemento de la pila, obtener su cima o
decapitarla, sta est vaca. Estas operaciones no deben producir
ningn efecto
Excepciones (II)

 Para Especificar completa y correctamente cada


operacin vlida de un TAD se debe indicar:
 Especificaciones Sintcticas.
 Especificaciones Semnticas.
 Excepciones: Se indicarn como parte de las
especificaciones semnticas.
Interfaz del TAD Pila
import java.io.*;
Define los mtodos de
public interface Pila {
objeto utilizados en la
void inicializarPila (); clase TAD_PILA
boolean pilaVacia ();
void eliminarPila ();
int cima ();
void apilar (int x);
int desapilar ();
void decapitar ();
void imprimirPila ();
void leerPila () throws NumberFormatException, IOException;
int numElemPila ();
}
Prueba (condiciones normales)
import java.io.*;
public class pruebaPila1 {
public static void main (String [] args) {
Pila p = new TadPila ();
int x;
p.inicializarPila ();
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 excepcin
public class pruebaPila2 {
public static void main (String [] args) {
Pila pila1 = new TadPila ();
int i, j;

pila1.inicializarPila ();
for (I = 1; I < 10; i++)
pila1.apilar (i);
j = pila1.desapilar ();
for (I = 1; I < 10; i++)
j = pila1.desapilar ();
pila1.eliminarPila ();
}
}
Algoritmos bsicos con Pilas
 Tratamiento recursivo.
 Ventaja: legibilidad.
 Inconveniente: consumo de memoria
 Justificacin:
 Adecuacin de la estructura a la tcnica.
 Restricciones del enunciado.
 Mecnica: desapilar llamar apilar.
 Terminaciones:
 Pesimista: Llegar al final.
 Anticipada: No llamar ms.
Ejemplos: Imprimir los elementos de una pila - Contar
los elementos de una pila

static void escribirPila (Pila pila) { static int contarPila (Pila pila) {
int elem; int elem, resul;
if (! pila.pilaVacia ()) { if (! pila.pilaVacia ()) {
elem = pila.desapilar (); elem = pila.desapilar ();
System.out.println (elem); resul = 1 + contarPila (pila);
escribirPila (pila); pila.apilar (elem);
pila.apilar (elem); }
} else resul = 0;
} return resul;
}
Obtener el duplicado de una pila
static void copiarPila (Pila pilaO, Pila pilaD) {
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 transicin: no hacemos nada
 Condicin de parada: pila vaca (sin terminacin anticipada)

Estado inicial

2 5 2

7 3 7

3 7 3

5 2 5
if (! pilaO.pilaVacia ()) {
elem = pilaO.desapilar ();
pilaD.apilar (elem);
invertirPila (pilaO, pilaD);
7

3 2 2

2 2 3 3 3

7 5 7 5 7 5 5

elem = 5 elem = 3 elem = 2 elem = 7


pilaO.apilar (elem);
}

5 7 7 7 7
3 2 3 2 2 2
2 3 2 3 2 3 3
7 5 7 5 7 5 7 5
Sumergir un elemento

 Consideraciones:
 Fase de ida: desapilamos elemento
 Condicin de parada: pila.pilaVacia () (sin terminacin
anticipada)
 Transicin:
 Apilamos el dato que queremos sumergir
 Fase de vuelta: restablecemos la pila, apilamos el
elemento
Sumergir un elemento

static void sumergir (Pila pila, int dato) {


int elem;
if (!pila.pilaVacia ()) {
elem = pila.desapilar ();
sumergir (pila, dato);
pila.apilar (elem);
}
else pila.apilar (dato);
}
Invertir los elementos de una pila

static void invertir (Pila pila) {


int elem;
if (!pila.pilaVacia ()) {
elem = pila.desapilar ();
invertir (pila);
sumergir (pila, elem);
}
}
Terminacin anticipada
 Parar la ejecucin del programa antes de alcanzar la condicin de
parada si se cumple determinada condicin
 No se realizan ms llamadas recursivas.
 Condicin de parada pesimista: pilaVacia.
 Ejemplo: buscar un valor.
 Condicin de parada pesimista: pilaVacia
 Terminacin anticipada: existe dato no se realizan ms llamadas
recursivas
 Fase de ida:
 desapilar elem de pila y comparar con dato
 Si igual termino llamadas recursivas
 Si no llamada a funcion recursiva
 Fase de vuelta: apilar elem en pila
Quitar el elemento del fondo

public static int desfondar (Pila p) {


int elem, dato;
if (!p.pilaVacia ()) {
elem = p.desapilar ();
if (! p.pilaVacia ()) {
dato = desfondar (p);
p.apilar (elem);
}
else dato = elem;
}
else {
System.out.println ("error, la pila est vaca");
dato = -9999;
}
return dato;
}
Buscar un valor

static boolean esta (Pila pila, int dato) {


int elem;
boolean resul;
if (!pila.pilaVacia ()) {
Terminacin
elem = pila.desapilar (); anticipada
if (elem == dato)
resul = true;
else resul = esta (pila,dato);
pila.apilar (elem);
} Terminacin
else resul = false; pesimista
return resul;
}
Varias Pilas: Mezclar dos Pilas (AND). (I). Estrategia
 Entrada: Dos pilas ordenadas ascendentemente (pila1 y pila2)
 Salida: Pila ordenada ascendentemente (pila3) con los elementos de pila1y de pila2 sin repeticiones.
 Argumentos:
 pila1, pila2, pila3: clase Pila.
 elem1, elem2: enteros. (No pueden ser variables locales).
 apilar1, apilar2: lgicos. (Elemento pendiente de apilar).
 Fase de ida:
 Variables de control: pend1 y pend2 (lgicos): La pila (1 2) tiene algo pendiente de tratar.
 Condicin de terminacin: Alguna de la pilas no tiene elementos por tratar (!(pend1 && pend2)
(!pend1 || !pend2).
 Tratamiento:
 desapilar segn proceda (utilizar apilar1|2).

 Comparar elementos de pila1 y pila2.

 Llamada recursiva con los valores oportunos de apilar1 y apilar2.

 Fase de transicin:
 apilar en pila1 o pila2 algn posible elemento pendiente.
 Fase de vuelta:
 apilar en pila1o pila2 segn el valor de apilar1|2.
 apilar en pila3 solo cuando se corresponda con una instancia de la fase de ida en la que elem1 =
elem2
Varias Pilas: Mezclar dos Pilas (AND). (II). Argumentos

 apilar1 y apilar2
 Segn lo que haya ocurrido en la instancia anterior:
pendiente de apilar en pila1 en pila2
 Se inicializan en la llamada externa al programa, ambas a
false.
 pend1 y pend2: quedan elementos por tratar en pila1|2
si no estn vacas (!pila1|2.pilaVacia ())o que dan
elementos por tratar (apilar1|apilar2)
 pend1 = (!pila1.pilaVacia () || apilar1)
 pend1|2 = (!pila2.pilaVacia () || apilar2)
Varias Pilas: Mezclar dos Pilas (AND). (III). Modelo
Varias Pilas: Mezclar dos Pilas (OR). (I). Estrategia
 Entrada: Dos pilas ordenadas ascendentemente (pila1 y pila2)
 Salida: Pila ordenada ascendentemente (pila3) con los elementos de pila1y de pila2 sin repeticiones.
 Argumentos:
 pila1, pila2, pila3: clase Pila.
 elem1, elem2: enteros. (No pueden ser variables locales).
 apilar1, apilar2: lgicos. (Elemento pendiente de apilar).
 Fase de ida:
 Variables de control: pend1 y pend2 (lgicos): La pila (1 2) tiene algo pendiente de tratar.
 Condicin de terminacin: Alguna de la pilas no tiene elementos por tratar (!(pend1 && pend2)
(!pend1 || !pend2).
 Tratamiento:
 desapilar segn proceda (utilizar apilar1|2).

 Comparar elementos de pila1 y pila2.

 Llamada recursiva con los valores oportunos de apilar1 y apilar2.

 Fase de transicin:
 Copiar el resto de la pila no vaca en pila3 ( Llamada al mtodo copiarPila).
 Tratar algn posible elemento pendiente de pila1 o pila2.
 Fase de vuelta:
 apilar en pila3.
 apilar en pila1o pila2 segn el valor de apilar1|2.
Varias Pilas: Mezclar dos Pilas (OR). (II). Argumentos
 apilar1 y apilar2
 Segn lo que haya ocurrido en la instancia anterior:
pendiente de apilar en pila1 en pila2
 Se inicializan en la llamada externa al programa, ambas a
false.
 pend1 y pend2: quedan elementos por tratar en pila1|2
si no estn vacas (!pila1|2.pilaVacia ()) o que dan
elementos por tratar (apilar1|apilar2)
 pend1 = (!pila1.pilaVacia () || apilar1)
 pend1|2 = (!pila2.pilaVacia () || apilar2)
Varias Pilas: Mezclar dos Pilas (OR). (III). Modelo
Varias Pilas: Mezclar dos Pilas (OR). (IV). Simulacin (I)
Ambas pilas tienen elementos por tratar (pend1 && pend2)
if (!apilar1)
If (!apilar1)
elem1 = pila1.desapilar (); [1] elem1 = pila1.desapilar ();
if (!apilar2)
elem2 = pila2.desapilar ();

1 2
5 4 5 4
7 6 7 6

elem1 = 1 elem1 = 5
elem2 = 2 elem2 = 2

if (elem1 < elem2) if (elem2 < elem1)


mezclarPila (pila1,pila2,pila3,false,true,1,2) mezclarPila (pila1,pila2,pila3,true, false,5,2);
[1] [2]
pila1.apilar (1); pila2.apilar (2);
pila3.apilar (1); pila3.apilar (2);
Varias Pilas: Mezclar dos Pilas (OR). (IV). Simulacin (II)
Ambas pilas tienen elementos por tratar (pend1 && pend2)
[2] if (! apilar2) [3] if (! apilar2)
elem2 = pila2.desapilar (); elem2 = pila2.desapilar ();

4
7 6 7 6

elem1 = 5 elem1 = 5
elem2 = 4 elem2 = 6

if (elem2<elem1) if (elem1<elem2)
mezclarPila(pila1,pila2,pila3,true,false,true,5,4); mezclarPila (pila1,pila2,pila3,false,true,5,6);
[3] [4]
pila2.apilar (4); pila1.apilar (5);
pila3.apilar (4); pila3.apilar (5);
Varias Pilas: Mezclar dos Pilas (OR). (IV). Simulacin (III)
Ambas pilas tienen elementos por tratar (aux1 && aux2)
[5] pend1; ! pend2; apilar1
[4] if (apilar1)
pila1.apilar (elem1);
if (!apilar1) pila3.apilar (elem1);
elem1 = pila1.desapilar ();

7 7 7
elem1 = 7
elem2 = 6

if (elem2 < elem1) FASE DE VUELTA


mezclarPila (pila1,pila2,pila3,true,false,7,6); [5]
pila2.apilar (6);
pila3.apilar (6);
Varias Pilas: Mezclar dos Pilas (OR). (IV). Simulacin (IV)
[5]
pila2.apilar (6);
pila3.apilar (6);
[4] 1
pila1.apilar (5); 2
pila3.apilar (5); 4
[3] 1 2 5
pila2.apilar (4);
5 4 6
pila3.apilar (4);
7 6 7
[2]
pila2.apilar (2);
pila3.apilar (2);
[1]
pila1.apilar (1);
pila3.apilar (1);
Varias pilas. Terminacin anticipada (I).
Ejemplo.
Mtodo que devuelve un valor lgico que indica si una pila de enteros ordenados
ascendentemente desde la cima hacia el fondo (pila2) est contenida en otra (pila1)
de las mismas caractersticas.
Es una variante del algoritmo de mezcla AND con terminacin anticipada si durante
la fase ida aparece un elemento de pila2 que no est en pila1 (elem2 < elem1).
 Fase de ida:
 Variables de control: pend1 y pend2 (lgicos): La pila (1 2) tiene algo pendiente de tratar.
 Condicin de terminacin (pesimista): Alguna de la pilas no tiene elementos por tratar
(!(pend1 && pend2) (!pend1 || !pend2).
 Tratamiento:
 desapilar segn proceda (utilizar apilar1|2).

 Comparar elementos de pila1 y pila2.

 Si elem1 elem2, llamada recursiva con los valores oportunos de apilar1 y apilar2.

 En otro caso (Terminacin anticipada). No hay ms llamadas.


Varias pilas. Terminacin anticipada (II).
 Fase de transicin:
 Por terminacin anticipada: Se apilan los elementos pendientes en pila1 y pila2
 Se devuelve false.
 Por terminacin pesimista. Posibilidades:
 Se ha terminado con pila2 (y no con pila1).
 Se apila el elemento pendiente de pila1
 Se devuelve true.
 Se ha terminado con pila1 (y no con pila2).
 Se apila el elemento pendiente de pila2
 Se devuelve false.
 Se ha terminado con ambas pilas.
 Se devuelve true.

 Fase de vuelta:
 apilar en pila1o pila2 segn el valor de apilar1|2.
 Se devuelve el resultado a la instancia de llamada.
En resumen. A la hora de manipular un TAD
 Qu tipo de problema? Crear un TAD a partir de otro, modificar el
contenido, realizar clculos con los elementos del TAD
 Parmetros:
 TAD por referencia.
 Otros argumentos: por referencia o por valor?.
 Cules estn implcitos en el enunciado y cules no pero son necesarios
 Requieren inicializacin? Dnde los inicializo (fuera del mdulo
recursivo, o dentro)?
 Condicin de parada
 Finalizacin anticipada: circunstancia que la provoca
 Diseo:
 Fase de ida: desapilar (+ operaciones)
 Transicin: se alcanza la condicin de parada y se realiza el proceso
correspondiente
 Fase de vuelta: (Operaciones +) apilar
Recapitulamos.

 Especificacin de un TAD:
 Propiedades sintcticas, propiedades semnticas y
excepciones
 TAD Pila
 Estructura LIFO (Last Input First Output)
 Recursividad
 Fase de ida fase de transicin fase de vuelta
 Desapilar Procesar Apilar

También podría gustarte