Sei sulla pagina 1di 16

BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA

Facultad de Ciencias de la Computación

Capítulo 10. Pilas y Colas

10.1 PILAS

La pila es una estructura de datos relativamente simple y muy utilizada en


informática en general y en programación en particular, tanto en programación de
aplicaciones como en programación de sistemas (desarrollo de lenguajes y compiladores).

Una pila (stak) es una estructura de datos, que consta de una serie de datos, en la
cual las inserciones y eliminaciones se hacen por un extremo, llamado la cima (top), de la
pila. La estructura pila se conoce también como LIFO (last-in, first-out, último en entrar,
primero en salir), que significa "último elemento introducido, primero sacado". Las
operaciones fundamentales de añadir y quitar elementos de la pila se hacen por un extremo
de pila llamado cima.
El concepto de pila, desde el punto de vista informático, es similar al concepto de
pila en el mundo real: una pila de platos, una pila de libros, etc.; en estas pilas los
elementos (platos, libros, etc.) sólo pueden añadirse por un extremo (la parte superior o
cima), y sólo pueden quitarse por ese mismo extremo.

Consideremos la estructura de pila de la figura I.1:


cima de la pila

E
D
C
B
A

Fig. 6.1. Estructura de pila.

La evolución de la pila tras diferentes operaciones de entrada y salida se muestran en la


figura 6.2.
cima
cima F cima
E E E cima
D D D cima D
C C C C C
B B B B B
A A A A A

estado inicial añadir F suprimir suprimir añadir D


de la pila

230
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

Fig. 6.2. Evolución de la pila tras diferentes operaciones de entrada/salida.


Las operaciones básicas que se asocian con una pila son:

-crear o inicializar inicializar una pila vacía


-pila vacía (empty) determinar si una pila está vacía
-meter (push) inserta un elemento en la cima de la pila
-sacar (pop) recupera y elimina el último elemento en la
cima de la pila

En teoría el tamaño de una pila no está limitado; sin embargo, en la práctica de la


programación existe una limitación física en el espacio reservado en memoria.
Una estructura pila puede ser realizada en Pascal utilizando un vector (array) cuyo
tamaño sea lo suficientemente grande para alojar los elementos iniciales, así como todas las
posibles inserciones que se puedan hacer.
La variable cima contiene el número de elementos actualmente en la pila y puede
ser utilizada como un subíndice o como un puntero al elemento superior de la pila. Si una
pila no tiene elementos, se dice que es una pila vacía. La variable o puntero cima se
incrementa en uno al poner un elemento en la pila y se decrementa en uno al quitar el
elemento.

Procedimientos
Crear (Pila): {crea-inicializa-limpia una pila vacía}
Meter (Pila, Elemento): {mete Elemento en Pila}
Sacar (Pila, Elemento): {sacar Elemento en Pila}

Función
Pila Vacía (Pila) {determina si Pila está vacía}
Pila Llena (Pila) {determina si Pila está llena}

Pila Elemento parámetros de los subprogramas

Tabla 6.1. Operaciones básicas sobre pilas

Pese a la similitud, es preciso notar que una pila no es igual que un vector. Una pila
es, por esencia, un objeto dinámico, mientras que un vector tiene un número máximo de
elementos, determinados por su definición; no es, pues, más que una representación de la
noción abstracta.
La estructura pila se realiza con un vector, cuyo índice representa el rango de un
elemento de la pila. Las operaciones fundamentales sobre la pila se representan a
continuación - mediante procedimientos y funciones - considerando un tipo de dato Tipo
Pila.

Antes de describir la realización de una pila y sus operaciones básicas vamos a


considerar las posibles situaciones de error que se pueden representar:

231
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

1. Intentar meter un elemento en una pila llena (error de desbordamiento, "overflow").


2. Intentar sacar un elemento de una pila vacía (error de desbordamiento negativo
"underflow").

Las operaciones Pila Llena y Pila Vacía devuelven "true" si la pila está llena o
vacía, y "false" en caso contrario. En general, antes de realizar una operación en una pila se
deberán evaluar las situaciones anteriores mediante las sentencias:
Antes de sacar un elemento x de la Pila
1. if not PilaVacía (Pila) then
Sacar (Pila, X)
else {mensaje de error al usuario}
{tratamiento del mismo}

Aantes de meter un elemento x en la Pila


2. if not PilaLlena (Pila) then
Meter (Pila, X)
else {mensaje de error al usuario}
{tratamiento del mismo}

El mejor sistema es poner un mensaje de error indicando „PilaLlena‟ o ‟PilaVacía‟,


o mejor incluso devolver en una variable lógica, por ejemplo Exito, el valor true si ha
tenido éxito la operación -se ha podido realizar- o bien false si se ha encontrado el error;
también se puede detener el programa con la sentencia Halt. Las sentencias para meter o
sacar elementos de una pila si p es la variable que representa la pila son:
meter sacar
cima := Cima + 1; X := Pila[Cima];
Pila[Cima] := X; Cima := Cima + 1;

Definición de la clase Pila

Un array es una estructura de datos muy eficiente para la implementación de una pila. La
implementación es muy sencilla:

Crear una clase Pila y utilizar esa clase para invertir un flujo de enteros.
1. Mediante una estructura estática.
2. Mediante una estructura dinámica.

// Definición de la clase pila


const int MAXPILA = 100; // tamaño por defecto de la pila
class pila
{
private:
int cuenta;
int items [MAXPILA]; // número de elementos de la pila
public:

232
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

pila( ); //inicializa la pila: constructor


void meter(int item); // añade un elemento a la pila
void sacar( ); // quita elemento superior a la pila
int cima( ); // devuelve elemento superior de la pila
int esvacia( ); // ¿está la pila vacía?
};

pila::pila( )
{
Cuenta = 0; //inicializa la pila
}
void pila::meter(int item) //añadir un elemento a pila
{
items[cuenta++] = item;
}
void pila::sacar( ) //quitar el elemento superior de la pila
{
cuenta--;
}

int pila::cima( ) // devuelve el elemento superior de la pila


{
return items[cuenta –1];
}

int pila::esvacia( ) // ¿está la pila vacía?


{
return cuenta = = 0;
}
Un programa que manipula la pila y que visualiza los elementos introducidos en orden
inverso

#include <iostream.h>
main( )
{
pila s;
int i; // crea una pila

while(cin >> i)
s.meter(i);
if(!cin.eof( )) return 1;

for(; !s.esvacia( ); s.sacar( ))


cont << s. cima ( ) << “\n”;
return;

233
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

El principal inconveniente de la implementación anterior es que su tamaño es fijo y debe


ser establecido en el momento de creación de la misma. Esto puede dar lugar a que en
algunas situaciones se sobrepase su tamaño máximo. Por otra parte, sobredimensionar la
pila para reducir la probabilidad de que esto ocurra supone un desperdicio de memoria.

Una versión mejorada de la clase Pila, se realizará definiendo una nueva clase mediante
asignación dinámica del array items. Los campos son diferentes: items es ahora un puntero
y se ha añadido un campo adicional longitud que almacena el tamaño de una pila dada.
Otra diferencia es que se ha cambiado el prototipo del constructor. Ahora tiene un
argumento opcional. El último cambio es que se ha añadido un prototipo para un destructor;
se necesita liberar el espacio asignado dinámicamente al constructor.

El listado siguiente contiene las operaciones revisadas de pila, aunque la mayoría son
similares. meter rechaza añadir a una pila llena, sacar rechaza quitar de una pila vacía y
cima devuelve cero si la pila estaba vacía. Se ha modificado el constructor para asignar
dinámicamente la pila utilizando new y el destructor libera un espacio utilizando delete. No
se puede llamar al destructor directamente, se llama automáticamente siempre que se sale
del bloque en que se ha creado una pila.

// definición modificada de la pila


// archivo pila2.h
const int MAXPILA = 100; // tamaño por defecto de la pila

class pila
{
int cuenta; // número de elementos de la pila
int *items; // pila
int longitud; // tamaño de la pila
public:
pila(int n= MAXPILA); // crear pila
pila( ); // liberar pila
void meter(int item); // añadir elemento a la pila
void sacar( ); // quitar elemento de la pila
int cima( ); // devuelve elemento superior de la pila
int esvacia( ); // ¿está la pila vacía?
};

pila :: pila(int n)
{
items = new int[n]; // crea pila
cuenta = 0; // inicializa pila a vacía
longitud = n; // elementos en la pila
}

234
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

pila :: pila( )
{
delete [ ] items;
}
void pila :: meter(int item) // añadir elemento a la pila
{
if(cuenta < longitud)
items[cuenta++] = item;
}
void pila :: quitar( ) // quitar elemento a la pila
{
if(cuenta != 0)
cuenta--;
}

int pila :: cima( ) // devuelve elemento de la pila


// (o 0)
{
return cuenta > 0? items[cuenta –1] : 0;
}

int pila :: esvacia( ) // esta la pila vacía


{
return cuenta = = 0;
}

235
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

10.2 COLAS

El diccionario de la Real Academia Española define una acepción de cola como


"hilera de personas que esperan turno para alguna cosa"; una hilera de vehículos
esperando pasar una frontera, una hilera de personas para entrar en un teatro, una hilera de
aviones en la pista esperando despegar, o una cola de trabajos en un sistema de
computadora que espera la disponibilidad de algún dispositivo de salida tal como una
impresora. En cada uno de estos ejemplos, los elementos se atienden en el orden en que
llegaron; es decir, el primer elemento en entrar (primero en la cola) es el primero en ser
atendido (salir).
Una pila es una estructura LIFO (Last-in-Fisrt-Out), una cola es una estructura
FIFO (First-In-First-Out: primero en entrar, primero en salir), también llamada -a veces-
estructura FCFS (First-Come-First-Served: primero que llega primero que se atiende).
Al igual que las pilas las colas son estructuras de datos en las cuales las operaciones
básicas a añadir y eliminar elementos se realiza en los extremos de la lista. Al contrario que
en las pilas cuyos elementos se añaden y borran por un extremo de la lista, en las colas los
elementos se borran por un extremo, llamado frente o cabeza (front, head), de la cola y los
elementos se añaden por el otro extremo, llamado final o fin (rear, tail).

Una cola (queue en inglés) es una estructura de datos lineal en la cual la inserción de
datos se realiza por uno de sus extremos, mientras que la extracción de datos se realiza por el
otro. De esta forma, se extrae siempre el elemento que más tiempo lleve dentro de la cola. Por ello,
una cola es una estructura FIFO (First In First Out).

Las operaciones principales en una cola son la de inserción y extracción de datos, llamadas
encolar (enqueue) y desencolar (dequeue).

Las operaciones básicas para realizar una cola son:

CrearCola(Q) Crea una cola vacía (sin elementos).


ColaVacía(Q) Determina si una cola está vacía: devuelve
true si la cola está vacía , false en caso contrario.
ColaLlena(Q) Devuelve true si la cola está llena; false
en caso contrario.
Insertar(Q,x)( enqueue) Añadir un elemento al final de la lista (siempre y
cuando la cola no esté llena).
Borrar(Q,x) (dequeue) Recupera y elimina el elemento que está al principio
(frente) de la cola.
ElementosCola(Q) Devuelve el número de las colas existentes en la cola.

236
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

Ejemplo :
Operaciones básicas en una cola de cuatro elementos.

CrearCola(Q)

Insertar(Q,a) a

Insertar(Q,b) a b

Insertar(Q,c) a b c

Insertar(Q,d) a b c d

Una cola es una estructura de datos adecuada para almacenar elementos que se
deben procesar en el orden que son generados.

10.2.1 APLICACIONES DE LAS COLAS

Las colas se utilizan con frecuencia en los sistemas informáticos, siempre que más
de un proceso requiera un recurso específico, tal como una impresora, una unidad de disco
o la unidad central de proceso. Tales procesos, al solicitar un recurso específico, se sitúan
en una cola a la espera de atender a ese recurso. Por ejemplo, diferentes computadoras
pueden compartir la misma impresora, y una cola spool se utiliza para planificar las
diferentes salidas.
Si una petición para un trabajo de impresión se realiza y la impresora está libre, se le
asigna inmediatamente ese trabajo. Mientras esta salida se está imprimiendo, otras tareas
pueden necesitar la impresora. Se sitúan en una cola de tipo spool para esperar su turno.
Cuando la salida del trabajo actual termina, la impresora se libera de ese trabajo y se
asigna a la primera tarea de la cola.
Otro uso importante de las colas en un sistema informático es para operaciones de
acoplamiento o adaptación de entrada/salida (imput/output buffering). La transferencia
de información, desde un dispositivo de entrada/salida, es una operación relativamente
lenta, y el proceso de un programa debe ser suspendido mientras se transfieran los datos, la
ejecución del programa se ralentiza drásticamente. Una solución frecuente a este problema
utiliza secciones de memoria principal conocidas como memorias intermedias (buffers) y
transfiere datos entre el programa y estas memorias intermedias, en lugar de entre el
programa y el dispositivo de entrada/salida directamente.
En particular, considérese el problema en el cual los datos procesados por un
programa se leen de un archivo de disco. Esta información se transfiere desde el archivo de
disco hasta una memoria intermedia de entrada en memoria principal mientras que la
unidad central de proceso (CPU) esta ejecutando alguna otra cosa. Cuando el programa
necesita de datos, se recuperan los siguientes valores almacenados en la memoria
intermedia. Mientras estos valores se están procesando, se pueden transferir valores de
datos adicionales desde el archivo del disco hasta la memoria intermedia. La memoria
intermedia (buffer) debe ser organizada como una estructura primero en entrar primero en
salir, es decir, una cola. Una condición de cola vacía indica que la memoria intermedia esta

237
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

vacía y la ejecución del programa se suspende mientras el sistema operativo intenta cargar
más datos en la memoria intermedia o señala el fin de la entrada. Naturalmente, tal
memoria intermedia tiene un tamaño limitado, y por consiguiente una condición de cola
llena se debe utilizar para indicar cuando la memoria intermedia está llena y ningún dato
más se tiene que transferir desde el archivo de disco hasta la misma.

Las operaciones de inserción y borrado en una cola son operaciones en las que las
inserciones se realizan por un extremo y la eliminaciones (borrados) por otro. En algunas
aplicaciones es necesario que las inserciones y eliminaciones se realicen en ambos
extremos. Una estructura tipo cola en que las inserciones y eliminaciones se realicen en
cualquiera de los extremos se llama bicola (deque, "doubleended stack").

frente final

Borrado inserción
Inserción Borrado

Otra estructura de datos relacionada con la cola es llamada cola de prioridad. En


esta estructura se asocia una cierta prioridad con cada elemento, y estos elementos se
almacenan de tal modo que los de prioridad más alta están cerca del frente de la cola, de
forma que se eliminan de la cola y atienden antes que los de menor prioridad.

10.2.2 Manejo de una Cola estática

// Programacion Avanzada
#include <iostream.h>
// Clase cola
class Cola
{
int c[100];
int e,s;
int tamanio;
public:
void inicia (void);
void pondato_cola (int i);
int sacadato_cola (void);
void pon_tamanio(int t){tamanio =t;}
};

/*Definicion de metodos */
void Cola::inicia(void)
{
e=s=0;
};

void Cola::pondato_cola(int i)

238
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

{
if (e == tamanio) {
cout << " La cola esta llena \n";
return;
}
c[e++]=i;
};

int Cola::sacadato_cola(void)
{
if (e == s) {
cout << " La cola esta vacia ";
return 0;
}
return c[s++];
};

/* Caracterizaci¢n de la clase Cola */


int main(void)
{
Cola a,b; // Objetos de la clase Cola
a.inicia();
b.inicia();
a.pon_tamanio(5);
b.pon_tamanio(8);
a.pondato_cola(10);
a.pondato_cola(20);
b.pondato_cola(100);
b.pondato_cola(200);
cout << "COLA A : " << a.sacadato_cola() << "\n";
cout << "COLA A : " << a.sacadato_cola() << "\n";
cout << "COLA A : " << a.sacadato_cola() << "\n";
cout << "COLA B : " << b.sacadato_cola() << "\n";
cout << "COLA B : " << b.sacadato_cola() << "\n";
return 0;
}

10.2.3 COLA CIRCULAR

Se considerará una cola de seis elementos tipo entero. La secuencia de operaciones


Insertar(Q,70), Insertar(Q,80), Insertar(Q,30) produce la configuración.

Final =4

70 80 30

Frente =1

Eliminar dos elementos

239
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

Final = 4

30

Frente=3

Añadir dos elementos:110, 60, y 40.

Final = 7

30 110 60 40

Frente= 3

Como la cola ya está llena, antes de poder insertar otro elemento en la cola, los
elementos de array se deben desplazar de nuevo al principio del array.

Final = 5

30 110 60 40

Frente = 3

Este desplazamiento se puede evitar si se piensa en un array de carácter circular, es


decir, el primer elemento viene después del último.
Como ya se ha expuesto, para realizar una cola se puede utilizar una estructura
registro que almacene los elementos de la cola y los campos frente y Final para registrar la
posición el elemento frontal y final, así como un campo de tipo array unidimensional
llamado elementos.

class Cola{
Int Frente, Final ;
TipoElemento Elemento[100];
Cola ( );
int ColaVacia ( );
int ColaLlena ()
void Insertar ();
void Borrar ()
};

El array o vector circular se puede realizar fijando el índice del array en 0 e


incrementando Frente y Final

Final=4

30 75 55

Frente=1

240
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

Frente=0

4
0
insertar 50 50
insertar 40
insertar 30 1 40 3 final =3
30
2

4
0
Eliminar
Eliminar
1 3 final =3
30
2 frente= 2

Final=0

4
0 55
insertar 75
insertar 55 75
1 3
30
2 frente =2

Para determinar si la cola esta vacía se tiene que verificar la condición


Frente=Final. Inicialmente, CrearCola fijará Fente y Final, ambas a cero. Veamos el
porqué de la condición Frentre = Final. Si la cola contiene un solo elemento, debe estar en
la posición Frente y Final es la posición libre siguiente a ella. Si este elemento se suprime,
Frente se incrementa en 1, de modo que Frente y Final tienen el mismo valor cuando la
cola esta vacía.
La detección de la condición pila llena se deduce de igual modo. Supongamos que
el array está casi lleno, con sólo una posición vacía MaxCola-1

0
1
2

Final Frente

241
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

Si un elemento se almacena en esa posición. Final se incrementará en 1 y por


consiguiente tendrá el mismo valor que Frente. Sin embargo, la condición Frente= Final
indica que la cola esta vaciá. Por tanto, no podremos diferenciar entre una cola vacía y una
cola llena, si esta posición se utiliza para almacenar un elemento. Se puede evitar esta
dificultad, si se mantiene una posición vacía (libre) en el array: la condición que indica si
una cola esta llena es entonces:

(Final + 1) mod MaxCola

Las operaciones básicas sobre las colas se realizarán, al igual que en el caso de las
pilas con subprogramas.
Cola::Cola ( );
(crea uan cola vacía con cero elementos)
{ {CrearCola}
Frente = 0 {inicializa puntero Frente y Final}
Final = 0
}
int Cola::ColaVacia ( )
{el valor de la función es true si la cola esta vacía}
{false en caso contrario}
{
return(.Frente = Final);
}
int Cola::ColaLlena ()
{devuelve true si la cola está llena; false en caso contrario}
Int Siguiente;
{localizar siguiente posición disponible}
if Final = MaxCola then
Siguiente: = Final+1;
Siguiente = Q.Final
return(siguiente);
}
void Cola:: Insertar ();
{//añade item al final de la lista; se supone que la cola no esta llena

int MaxPos = MaxCola -1;


int Siguiente;

Siguiente: = (Final + 1 ) mod MaxCola;


if (Siguiente != Final )
{
Elementos [Final] : = Item;
Final : = Siguiente
}

void Cola::Borrar ()
{//recuperar Item y borrarlo del principio de la cola, suponiendo que la cola noe este vacia

242
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

If (!ColaVacia() )
{
Item = Elementos [Frente];
Frente = (Frente +1) mod MaxCola
}

10.3 Pilas con Java

public class pila // clase pila estatica


{ int tope,tam;
int P[]= new int[100];
public pila(int t) // Constructor para asignar tamaño a la pila
{ tam=t;
tope=0;
}
public void push(int dato) // Inserta un dato en la pila
{ P[tope]=dato;
tope++;
}

public int pop() // Extrae un dato de la pila


{ int n;
tope--;
n=P[tope];
return (n);
}
public int pop2() // Muestra el dato en el tope de la pila
{
return (P[tope-1]);
}

public int vacia() // Verifica si la pila esta vacia


{
if(tope==0) return 1;
else return 0;
}
public int llena() // Verifica si la pila esta llena
{
if(tope==tam) return 1;
else return 0;
}

243
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

public void muestra() // Muestra los datos en la Pila


{
for(int i=0;i<tope;i++)
System.out.println(P[i]);
}

public void invertir(pila P1)


{

int t=P1.tope;
for (int i=0;i<t;i++)
this.push(P1.pop());

10.4 Colas con Java

import javax.swing.*;
public class cola
{
int entrada, salida,tam;
String C[]= new String[100];
public cola(int t)
{
tam=t;
entrada=salida=0;
}
public void insertar(String dato)
{
C[entrada]=dato;
entrada++;
}
public String extraer()
{
String n;
n=C[salida];
salida++;
return (n);
}
public int vacia()
{
if(entrada==salida) return 1;
else return 0;
}

244
BENEMÉRITA UNIVERSIDAD AUTÓNOMA DE PUEBLA
Facultad de Ciencias de la Computación

public int llena()


{
if(entrada==tam) return 1;
else return 0;
}
public void muestra()
{
String datos="Datos de la COLA\n";
for(int i=salida;i<entrada;i++)
datos=datos+C[i]+"\n"; JOptionPane.showMessageDialog(null,datos,"Estado de la
Cola",JOptionPane.INFORMATION_MESSAGE);
}
public static void main(String args[])
{ String opcion,menu,n;
int opc;
opcion=JOptionPane.showInputDialog("TAMAÑO DE LA COLA: ");
cola q=new cola(Integer.parseInt(opcion));
menu=" Manejo de una COLA\n 1.- INSERTAR \n 2.- ELIMINAR \n 3.-
MOSTRAR\n "+ "0.- SALIR\n\n Introduce tu Opcion: ";
do{
opcion=JOptionPane.showInputDialog(menu);
opc=Integer.parseInt(opcion);
switch (opc)
{
case 1: opcion=JOptionPane.showInputDialog("Introduce un NUMERO:");
//n=Integer.parseInt(opcion);
if (q.llena()==1)JOptionPane.showMessageDialog(null,"COLA LLENA",
"Estado de la COLA",JOptionPane.INFORMATION_MESSAGE);
else q.insertar(opcion);
break;
case 2:
if(q.vacia()==1)JOptionPane.showMessageDialog(null,"COLA VACIA",
"Estado de la COLA",JOptionPane.INFORMATION_MESSAGE);
else { n=q.extraer();
JOptionPane.showMessageDialog(null,"Dato extraido = "+n,"Eliminar dato",
JOptionPane.INFORMATION_MESSAGE);
}
break;
case 3: q.muestra();
break;
case 0: JOptionPane.showMessageDialog(null,"FIN de la
Aplicacion","SALIR", JOptionPane.INFORMATION_MESSAGE);
break;
default: JOptionPane.showMessageDialog(null,"Opcion no valida","Error",
JOptionPane.ERROR_MESSAGE);
}
}while (opc!=0);
System.exit(0);
}}

245