Está en la página 1de 27
OBJETIVOS Después de haber lefdo y estudiado este capitulo usted podré: + Especificar el tipo abstracta de datos pila, + Conocer aplicaciones de las pilas en Ia prograrhacién, + Definir ¢ implementar la case pila, ‘+ Especificar el tipo abstracto de datos cola. + Encontrat as diferencias fundamentales entre pilas y colas. + Definir una clase cola con arrays. + Definir una clase cota com tistas enlazadss. + Realizar una cola de prioridades, CONTENIDO 15.1. Concepto de pita 15.2. El tipo pila implementado con arrays. 15.3. Colas. 15.4. Colas implementadas con arrays. 15.5. Realizacién de una cots con una lista entazada, 15.6. Colas de prioridades. Resumen. Ejercicios. Problemas. INTRODUCCION ian on detalle las estructuras de datos pias y col S01 Tamas mAs ustiales, Son estructaras de datos que alia en también como: probablomente la ui icenan y ree 490 Programacién en JAVA 2 15.1. CONCEPTO DE PILA Una pila (stack) es una colecciGn ordenada de elementos alos que sélo se puede acceder por un tnico lugar 0 extremo de la pila. Los elementos de la pila se afiaden 0 quitan (borran) de la misma s6lo por su parte superior (cima). Este es el caso de una pila de platos, una pila de libros, etc, ‘Una pila es una estructura de datos de entradas ordenadas tales que s6lo se pueden introducir y liminar por un extremo, llamado cima, Cuando se dice que la pila est ordenada, lo que se quiere decir es que hay tin elemento al que se puede acceder primero (cl que esté encima de la pila), otro elemento al que se puede acceder en segundo lugar (justo el elemento que esti debajo de la cima), un tercero, etc. No se requiere que las entradas se puedan comparar utilizando el operador «menor que> (<) y pueden ser de cualquier tipo Las entradas de la pila deben ser eliminadas en el orden inverso al que se situaron cn la misma. Por ejemplo, se puede crear una pila de libros, situando primero un diccionario, encima de él una enciclopedia y encima de ambos una novela, de modo que la pila tendré la novela en la parte superior. Enciclopedia Diccionario Figura 15.1. Pila de libros. Cuando se quitan los libros de la pila, primero debe quitarse la novela, luego la enciclopedia y por iltimo el diccionario. Debido a su propiedad especifica «ciltima en entrar, primero en salir», se conoce a las pil estructura de datos LUFO (last-in, first-out). Las operaciones usuales en la pila son Insertar y Quitar. La operaci6n Insertar (push) afiade un elemento en la cima de la pila, y la operacién Quitar (pop) elimina o saca un elemento de Ia pila. La Figura 15.2 muestra una secuencia de operaciones Insertar y Quitar. El dltimo elemento afiadido a la pila es el primero que se quita de la pila. -om0 Insert M Insert A Insert C QuitarC = QuitarA == Quitar M c A A A M M uM M | om Eotrada: Mac Salida: cans Figura 15.2. Poner y quitar elementos de fa pila. La operacién Insertar (push) sittia un elemento dato en la cima de la pila, y Quitar (pop) elimina © quita el elemento de la pila. Pilasycolas 497 > Cima =< Fondo Figura 15.3. Operaciones basicas de una pila La pila se puede implementar mediante arrays, en cuyo caso su dimensién o longitud es fija, y mediante listas enlazadas, en cuyo caso se utiliza memoria dinémica y no existe limitacién en su tamafio, excepto la memoria del ordenador. ‘Una pila puede estar vacfa (no tiene elementos) o Hlena (en el easo de tener tamaifo fijo, si no caben més elementos en la pila). Si un programa intenta sacar un elemento de una pila vacia, se produciré un error, una excepcién, debido a que esa operacién es imposible; esta situacién se denomina deshordamiento negative (underflow). Por el contrario, si un programa intenta poner un elemento en ung pila lena se produce un error llamado deshordamiento (overflow) o rebosamiento. Para cvitar estas situaciones se disefian métodos que comprueban si la pila esté lena o vacia, 15.1.1. Especificaciones de una pila Las operaciones que sirven para definir una pila y poder manipular su contenido son las siguientes (no todas ellas se implementan al definir una pila): Tipo de dato Dato que se almacena en ta pita, Insertar (push) Tnsertar un dato en la pila. Quitar (pop) Scar (quitar) un dato de Ia pila Pila vacia Comprobar si la pila no tiene elementos. Pila lena Comprobar si la pila est Hlena de elementos, Limpiar pila Quitar todos sus elementos y dejar la pila vacta, Cima Obtiene el elemento cima de la pila. Tamaio de la pila Nimero de elementos maximo que puede contener la pila. 15.2. EL TIPO PILA IMPLEMENTADO CON ARRAYS: Una pila se puede implementa mediante arrays o mediante listas enlazadas. Una implementacién estitica se realiza utilizando un array de tamaio fijo y una implementacién dinémica mediante una lista enlazada. La clase Pila implementada con arrays incluye una lista (array) y un indice a la cima de la pila, ademés de una constante con el miximo nimero de elementos. Al utilizar un array para contener los ‘elementos de la pila hay que tener en cuenta que el tamatio de la pila no puede exceder el mimero de elementos del array, y la condicién pila llena serd significativa para el disefio. 492 Programaci6n en JAVA 2 El método usual de introducir elementos en una pila es definir el fondo de la pila en la posicién 0 del array y sin ningdn elemento en su interior, es decir, definir una pila vaca; a continuacién se van introduciendo elementos en el array (en la pila), de modo que el primer elemento afiadido se introduce ‘en una pila vacia y en la posicién 0, el segundo clemento en la posicién 1, el siguiente en la posicién 2, y asf sucesivamente. Con estas operaciones el indice que apunta a la cima de la pila se va incrementando ‘en 1 cada vez que se afiade un nuevo elemento. Los algoritmos de introducir «insertar> (push) y quitar «sacar» (pop) datos de Ia pila: Insertar ‘(push) 1. Verificar si la pila no esta llena. 2. Incrementar en 1 el puntero indice de la pila. 3. Almacenar elemento en la posicién del puntero de la-pila. Quitar (pop) 1. Si la pila no esta vacia: 2. Leer el elemento de la posicién del puntero de la pila. 3. Decrementar en 1 el puntero de la pila. En el caso de que el array que define la pila tenga TaMPTLA elementos, las posiciones del array, es decir, el indice o puntero de la pila, estarén comprendidas en el rango 0 a TAMPILA-1 elementos, de modo que en una pila lena el puntero de la pila apunta a TAMPILA~1 y en una pila vacfa el puntero de la pila apunta al, ya que 0, te6ricamente, seri el indice del primer clemento. EJEMPLO 15.1. Una pila de siete elementos se puede representar grdficamente asi: aaa puntero de la pila = puntero de la pila = 6 puntero de fa pila Sise almacenan los datos A, B, C,.. . en a pila se puede representar gréficamente de alguna de estas formas: 1 Pilasycolas 493 ‘Veamos ahora cémo queda Ja pila en funci6n de diferentes situaciones de un posible programa: Pila vacta PunteroPila = Insertar 50 PunteroPila = 0 ee Insertar 25 PunteroPila = 1 ae eee 7 Insertar 100 ee eae | PunteroPila = 2 6 { Quitar so | 25 PunteroPila = 1 15.2.1. Especificacion de la clase Pila La definicién de una pila incluye los datos y operaciones ya citados anteriormente, 1, Datos de la pila (tipo de dato primitivo, o un tipo clase, o para generalizar de tipo Object) . 2. Verificar que la pila no esté Tena antes de intentar insertar o poner («push») un elemento en la pila; verificar que una pila no est vacia antes de intentar quitar 0 sacar («pop») un clemento de Ia pila. Si estas precondiciones no se cumplen se debe visualizar un mensaje de error y el programa debe terminar. . Pilavacia devuelve verdadero si la pila estd vacfa y falso en caso contrario. 4, pilaziena devuelve verdadero si la pila esté Lena y falso en caso contrario. Estos dos tiltimos :étodos se utilizan para verificar las operaciones det pérrafo 2. 5, LimpiarPila. Se limpia o vacia la pila, dejandola sin elementos y disponible para otras tareas. 6. Cima, devuelve el valor situado en la cima de la pila, pero no se decrementa el puntero de la pila, ya que la pila queda intacta. Defir package pilaistatica; ion public class Pila t private static final int TAMPILA = 49; 494 Programacién en JAVA 2 private int cima; private TipoDeDato []listaPila; public Pila() { cima = -1; // condicién de pila vacia listapila = new TipoDeDato['TAMPILA] ; } // operaciones que modifican la pila public void insertar (TipoDeDato elemento) {...}; public TipoDepato quitar(){... public void limpiarPila(){...}; //operacién de acceso a la pila public TipoDebato cima(){...}; // verificacién estado de la pila public boolean pilaVacia(){...}; public boolean pilablena(){...}; } Antes de definir las operaciones conviene recordar que'el 7ipopeDato puede ser desde un tipo primitivo, como int, char, double o bien si se quiere generalizar, el ipo referencia a object . Esta es la clase base de todas las clases de Java y por tanto hay una conversiGn automiética de cualquier referencia a Object. EJEMPLO 15.2, Escribir un programa que cree una pila de enteros y se realicen operaciones de afia- dir datos a la pila, quitar... Se supone implementada la clase pila con el tipo primitivo int. El programa orea una pila de nimeros enteros, inserta en Ja pila un dato lefdo del teclado y visualiza el elemento cima, El bloque de sentencias se encierra en un try para tratar errores de desbordamiento de la pila import pilakstatica; import java.io.*; class BjemploPila public static void main(string [J a) one pila; int x; i BufferedReader entrada = new BufferedReader ( new InputStreanieader (System. in)) try ( pila = new Pila(); // crea pila vacia System.out print ("Teclea un elemento para Ja pila: "); System. out. flush () ; x = Integer.parseInt (entrada. readbine()) ; pila.insertar (x); system.out print ("teclea un nuevo elemento: "); System.out .flush(}; x = Integer.parseInt (entrada. readline()) ; pila.ingertar (x); System.out.printin(*\ncima de la pila:" + pila.cima()); Pilas ycolas 495 pila.limpiarPila(); // 1a pila queda vacta } catch (Exception er) { system.err.println("Excepcion: “ + er); 15.2.2, Implementacién de las operaciones sobre pilas ‘Los métodos de Ia clase Pi 1a se implementan fécilmenté, teniendo en cuenta la caracteristica principal de esta estructura: inserciones y borradas se realizan por el mismo extremo, la cima de la pila. La operacién insertar() y quitar() afiaden y eliminan, respectivamente, un elemento de la pila; la operacién cima permite a un cliente recuperar los datos de la cima de la pila sin quitar realmente el elemento de la misma. La operacién de insertar un elemento en la pila incrementa el puntero cima de la pila en ly signa el nuevo elemento a la lista. Cualquier intento de afiadir un elemento en una pila Hena genera una excepci6n o error debido al «Deshordamiento de la pila». i public void insertar(TipoDeDato elemento) throws Exception { if (pilablena()) throw new Exception ("Desbordamiento pila”); } //incrementar puntero cima y copia elemento cimat+; listaPila[cima] = elemento; } La operacién qui tax elimina un elemento de la pila copiando primero el valor de la cima de la pila enuna variable local auxiliar y a continuaci6n decrementa el puntero de la pila en 1. La variable aux se devuelve en la ejecucién de la operacién qui tax. Si se intenta eliminar o borrar un elemento en una pila vacia se produce error, se lanza una excepcidn general. Antes de quitar Después de quitar | Bam | elemento | | Be | | * t 82 dowoe cima cima = cima-1 iene public TipoDeDate quitar() throws Exception - { ‘TipoDeDato aux; 496 — Programacién en JAVA 2 if (pilavacia()) { throw new Exception ("Pila vacia, no se puede extraer."); } // gaardar elemento de la cima aux = listaPila [cima]; // decrementar cima y devolver elemento cima return aux; 15.2.3. Operaciones de verifica n del estado de la pila Se debe proteger la integridad de 1a pila, para lo cual el tipo PiLa ha de proporcionar operaciones que comprueben el estado de la pila: pila vacta o pila lena, Asi mismo se ha de definir una operacién que restaure la condicién inicial de la pila, que fue determinada por el constructor por defecto de Pila (cima de la pilaa—1), LimpiarPila EI método pi1avacia comprueba (verifica) si la cima de la pila es -1. En ese caso, la pila esta vacia y se devuelve verdadero; en caso contratio, se devuelve falso. public boolean pilavacia() ( } return cima 1; EI método pilatlena comprueba (verifica) si la cima es TAMPILA~1. En ese caso, la pila est lena y se devuelve verdadero; en caso contrario, se devuelve falso. public boolean pilablena() { return cima == TAMPILA-1; } Por diltimo, Ia operaci6én 1impiarPila pone la cima de Ja pila a su valor inicial: public void limpiarPila() { : cima = -1; } EJERCICIO 15.1. Escribir un programa que uiilice la clase Pi la para comprobar si una determina- da frase/palabra (cadena de caracteres) es un palindromo. Nota: una palabra 0 frase es un palindromo cuando la lectura direcia e indirecta de la misma tiene igual valor: alila es un palindromo; cara (arac) no es un palindromo. La palabra se lee con el método readine (), que se almacena en un string; cada cardcter de Ja palabra leida se inserta en una pila de caracteres. Una vez lefda la palabra y construida Ia pila, se compara el primer cardcter del string con el caricter que se extrac de la pila, si son iguales sigue la comparacién con siguiente cardcter del string y de fa pila; asf hasta que la pila se queda vacta o hay un cardcter no coincidente. | | | | | | | | Pilas ycolas 497 Al guardar los caracteres de la palabra en Ja pila se garantiza que las comparaciones son entre caracteres que estén en orden inverso: primero con tiltimo La clase Pila se codifica de nuevo, sélo cambia que el tipo de los elementos es el tipo primitivo char, import java.io.*; clase Pila { private static final int TAMPILA = 79; private int cima; private char []listaPila; public Pila() it cima = -1; listaPila = new char(TAMPILA] ; } public void insertar(char elemento) throws Exception ( if (pilablena()) throw new Exception("Desbordamiento pila”); | } | listaPilalcima] = elemento; | a | public char quitar() throws Exception { char aux; if (pilavacia()) { throw new Exception ("Pila vaca, no se puede extraer.”); ListaPila [cima] ; } public boolean pilaVacia() { } public boolean pilaLlena() { } public void LimpiarPila() { xeturn cima = oat veturn cima == TAMPILA-1; 498 — Programacién en JAVA 2 class Palindrono { public static void main(String [] a) Pila pilachar; char ch; boolean esPal; string pal; BufferedReader entrada ~ new BufferedReader ( new InputStreanReader (System. in)); try { pilaChar = new Pila(); // crea pila vacia System.out print (*Teclea 1a palabra” + ‘a verificar si es palindromo: System.out..£lush() ; pal = entrada.readbine() ; // se crea 1a pila con los caracteres de la palabra pilaChar = new Pila(); for (int i-0; ic pal.length(); | pilaChar.insertar(pal.charAt (it+)); y // se comprueba si es palindromo esPal = true; for (int j=0; esPal &@ !pilaChar.pilavacia(); ) { esPal = pal.charat (j++) } pilaChar.limpiarPila(); pilaChar.quitar() ; if (esPal) Sytem.out.printin(*La palabra * + pal + “es un palindromo \n"); else sytem.out.println(*ba palabra * + pal + * no es un palindromo \n"); oe (Bxception er] ' system.err.printIn(*Excepeion: * + er); ; } 15.3. COLAS ‘Una cola cs una estructura de datos que almacena elementos en una lista y permite acveder a los datos por uno de los dos extremos de fa lista (Figura 15.4). Un elemento se inserta en la cola (parte final) de Ja lista y se suprime o elimina por el frente (parte inicial, frente) de la lista. Las aplicaciones utilizan una cola para alinacenar elementos en su orden de aparicién 0 coneurrencia, Piles ycolas 499 r 2 Ultimo Frente Final Figura 15.4, Una cola. Los elementos se eliminan (se quitan) de la cola en el mismo orden en que se almacenan y, por consiguiente, una cola es una estructura de tipo FIFO (first-in/first-oul, primero en entrarfprimero en salir, 0 bien primero en llegar/primero en ser servido). Fl servicio de atencidn a clientes en un almacén es un ejemplo tipico de cola. La accién de gestién de memoria intermedia (buffering) de trabajos o tareas de impresora en un distribuidor de impresoras (spooler) es otro ejemplo tipico de cola’, Dado que la ‘impresién es una tarea (un trabajo) que requiere més tiempo que el proceso de la transmisin real de los datos desde la computadora a la impresora, se organiza una cola de trabajos de modo que los trabajos se imprimen en el mismo orden en que se recibieron por la impresora. Este sistema tiene el gran inconveniente de que si su trabajo personal consta de una vinica pagina para imprimir y delante de su peticién de impresién existe otra peticién para imprimir un informe de 300 paginas, deberd esperar ala impresiGn de esas 300 paginas antes de que se imprima su pagina. Desde el punto de vista de estructura de datos, una cola es similar a una pila, en donde los datos se almacenan de un modo lineal y el acceso a os datos s6lo esta permitido en los extremos de la col: Las acciones que estén permitidas en una cola son: © Creaci6n de una cola vacta, + Verificacién de que una cola esta vacia, * Afjadir un dato al finat de una cola. * Bliminacién de los datos de la cabeza de fa cola. x Insertar x frente final x] oy Insertar y frente final x}oy [2 Insertar z frente final Recordemos que este caso sucede en sistemas multiusuatio, donde bay varios terminates y s6lo una impresora de servicio, 1Los trabajos se «encolan» en la cola de impresién. 500 = Programacién en JAVA 2 y | 2 quitar x frente final z Quitar y frente final Figura 15.5. Operaciones de insertar y quitar en una cola, 15.4. COLAS IMPLEMENTADAS CON ARRAYS ‘Al igual que las pilas, las colas se pueden implementar utilizando arrays o listas enlazadas. En esta secci6n consideraremos la implementacién utilizando arrays. La definicidn de una Cola ha de contener ‘un array para almacenar los elementos de la cola, y dos marcadores 0 punteros (Variables instancia) que manticnen las posiciones frente y final de la cola; es decir, un marcador apuntando a la posicidn de la cabeza de Ia cola y el otro al primer espacio vacfo que sigue al final de la cola. Cuando un elemento se afiade a la cola, se verifica si el marcador final apunta a una posici6n valida, entonces se afiade el elemento ala cola y se incrementa el marcador final en 1. Cuando un elemento se elimina de la cola, se hace una prueba para ver si Ia cola est vacia y, si no es asf, se recupera el elemento de la posicién apuntada por el marcador (puntero) de cabeza y éste se incrementa en 1 Este procedimiento funciona bien hasta la primera vez que el puntero de cabeza o cabecera alcanza clextremo del array y éste queda o bien vacfo o bien leno. 15.4.1, Definicion de la clase cola Una cola debe manejar diferentes tipos de datos; por esta circunstancia, tos elementos han de ser de un tipo genérico. En Java todavia no est definido el tipo genérico, sin embargo utilizando objetos y referencias, el tipo del elemento de una cola puede ser Object, que es la clase base de cualquier clase definida en Java. En esta primera definicién se deja abierto el tipo de los elementos, se supone que es de Tipodenato. La clase Cola contiene un array (1istaQue) , cuyo méximo tamaiio se determina por la constante MAXTAMD, Se definen dos tipos de variables puntero 0 marcadores, frente y ultimo. Estos son los punteros de cabecera y cola o final, respectivamente, Las operaciones bésicas del tipo abstracto de datos cola: insertarQ, eliminarg, queVacia,queLlena, y £renteQ. insertarg toman un elemento del tipo TipoDeDato y lo aftaden al final de la cola. e1iminazg suprime (quia) y devuelve el elemento de la cabeza o frente de la cola. La operacién frent-eg devuelve el elemento que esté en la posiciGn frente de la cola, sin eliminar el elemento y por tanto no modifica fa cola. En Jas operaciones de control, quevacia comprueba si la cola esta vacta; es necesaria esta comprobacién antes de eliminar nn elemento; quetilena comprueba si la cola esta lena, esta comprobaci6n se realiza antes de insertar un nuevo miembro. Si las precondiciones para insertaro Y eliminaxo se violan, el programa debe generar una excepciGn o error. - | | Pitasycoias 501 package colaArray; public class Cola { private static final int MAKTANQ = 39; private int frente; private int ultimo; private TipoDeDato []listaQ; public Cola() { frente = 0; ultimo = -1; listaQ = new TipoDeDato [MAXTANQ]; // operaciones de modificacién de 1a cola public void insertarQ(‘TipoDeDato elemento) throws Exception if (1queblena()} ListaQue [+4ultimo] = elemento; } else throw new Exception(*Overflow en la cola"); } public TipoDeDato elininarQ() throws Exception { Af (1queVacia()) { } else throw new Exception(*Cola vacia °); return listaQue[frente++] ; } public void borrarCola() { frente = ultimo = -1 } // acceso a la cola public Tipobeato frented() { if (Iquevacia()) { return listaQue [frente] ; } else throw new Exception(*Cola vacia “); // métodos de verificacién del estado de la cola public boolean queVacia() { return frente>ultimo; 502 Programacion en JAVA 2 } public boolean queblena () { return ultimo==MAXTAMQ-1; } } 15.4.2. Definis Esta implementacién de una cola es notablemente ineficiente, se puede alcanzar la condicién de cola llena habiendo elementos del array sin ocupar, Esto es debido a que al realizar la operacién de eliminar un elemento avanza ¢l frente, y por consiguiente las posiciones anteriores quedan desocupadas, no accesibles. Una solucién a este problema es hacer que frente no se incremente y ala vez desplazar todos los elementos una posicidn a la izquierda. Entonces se afiadirfa el método: private void desplazar () { for (int j=0; jeultimo-1; j++) istaQue[j] = listaQue[j+1] ; ultimo: } El método e1iminar queda: public TipoDeDato eliminarQ() throws Exception { if { TipeDeDato aux; aux = listaQue [frente] ; desplazar(); veturn aux; } else throw new Exception(*Cola vacia *); quevacia()) nde una cola con un array circular Ena operacién de e1iminar, la altemativa de desplazar los elementos del array de modo que Ta cabeza de la cola vuelve al principio del array es costosa en términos de tiempo de computadora, especialmente si los datos almacenados en el array son estructuras de datos grandes. El medio més eficiente, sin embargo, para almacenar una cola en un array es utilizar un tipo especial de array que una el extremo final de la cola con su extremo cabeza. Tal array se denomina array circular y permite que el array completo se utilizaré para almacenar elementos de Ia cola sin necesidad de que ningtin dato se desplace. Un array circular con n clementos se visualiza en la Figura 15.6. El array se almacena de modo natural en la memoria tal como ua bloque lineal de n elementos. Se necesitan dos marcadores (punteros), frente y final’, para indicar la posiciGn del elemento que precede a la cabeza y la posici6n del final, donde se elmacené el dltimo elemento afiadido. Una cola vacfa se representa por la condicién frente + tinal, La palabra £nal es una palabra reservada, en la ondificacién se sustituye por Lt imo, Pilasycolas 503 La variable frente es siempre la posicién del elemento que precede al primero de la cola y se avanza en el sentido de las agujas del reloj. La variable £ ina. es Ta posicién en donde se hizo la iltima insercién; una nueva insercién supone mover £inal circularmente a Ia derecha, mt 0 Figura 15.6. Un array circular. ae Mente —— final Figura 1.7. Una cola vacia. La implementaci6n del movimiento circular se realiza utilizando la teoria de los restos: Mover £inal adelante (final + 1) % MAXTAMQ Mover frente adelante (frente + 1) % MAXTAMQ Los algoritmos que formalizan la gestién de colas en wn array circular han de incluir al menos las siguientes tareas: © Creacién de una cola vacfa: frente = final = 0. * Comprobar si una cola esté vacfa’ es frente Figura 15.8. Una cola que contiene un elemento. 504 = Programacién en JAVA 2 * Comprobar si una cola esté lena: (final + 1) % MAXTAMQ == frente ? * Afiadir un elemento a la cola: si la cola no esté lena, afladir un elemento en Ia posicién siguiente a final y se establece: final = (final + 1) % MAXTAMQ © Eliminaci6n de un elemento de una cola: si la cola no est vacfa, suprimirlo de la posicién siguiente a frente y-establecer frente - (frente + 1) % MAXTAMO 15.4.3. Definicién de la clase cola con un array circular Las variables instancia no cambian respecto a Ja definicién de una cola considerando un atray lineal. En, cesta neva definici6n, la operaciGn de mover indices se realiza con el método privado siguiente () , que aplica la teorfa de restos para avanzar el Erente el ultimo (final) de la cola. package colaArrayCircular; public class Cola { private static ultimo int MAXTAMQ = 99; private int frente; private int ultimo; private TipoDeDato [] ListaQue; private int siguiente(int r) { return (x41) $MAXTAMQ; ] public Cola() { frente listad ultimo = 0; new TipoDeDato [MAXTAMQ] ; } // operaciones de modificacién de la cola public void insertarQ(TipoDeDato elemento) throws Exception { i€ (Iqueblena()} { ultimo = siguiente (ultimo) ; listague [ultimo] = elemento; } else throw new Exception ("Overflow en la cola”); } public TipoDeDato eliminarQ() throws Exception { + 4f (1quevacia()) frente = siguiente(frente); return listaQue [frente] ; } . else Pilasycoles 505 throw new Exception(*Cola vacia *) } public void borrarCola() ( } frente = ultimo =0; // acceso a la cola public TipoDeDato frenteQ() if (IqueVacia()) { return listaQue [siguiente (frente) ; } else throw new Bxception(*¢ola vacia "); {/ métodos de verificacién del estado de la cola public boolean quevacia() { return frente } public boolean quellena() { return siguiente(ultimo) == frente; } ultimo; } 15.5. REALIZACION DE UNA COLA CON UNA LISTA ENLAZADA La realizacién de una cola mediante una lista enlazada permite ajustarse exactamente al néimero de elementos de la cola. Esta implementaci6n utiliza dos referencias para acceder a la lista, frente y final. Lareferencia frente apunta al primer elemento de la cola, el primero en ser retirado de la cola. La referencia £ina1 apunta al tiltimo elemento en ser afiadido, el titimo que serd retirado. Al ser una estructura dinémica puede crecer y decrecer segtin las necesidades (el limite esté en la ‘memoria libre del computador), y por tanto no tiene sentido la operacién que prueba si Ia cola esté llena. frente ' . final ' fe [Le [Ls [- | C1, Gx, 8, Son valores del tipo TipoDeDato Figura 15.9. Cola con lista enlazada (representacién gratica tipica). 506 = Programacién on JAVA 2 15.5.1. Definicion de la clase cola con listas enlazadas La representacién del tipo abstracto de datos cola con listas enlazadas maneja dos clases; la clase Nodo y la clase Cola. En el Nodo se encapsulan los elementos de Ja estructura, en Cola se definen las variables frente y ultimo (final) , y las operaciones bisicas. package colaDinamica; public class Nodo { VipoDeDato dato; Nodo enlace; public Nodo(TipoDeDato t) { dato = t; enlace = null; } } public class Cola { private Nodo frente; private Nodo ultimo; // constructor: crea cola vacia public Cola() { frente = ultimo } // insertar: afiade elemento por el ultimo public void insertarQ(TipoDePato elemento) - { Nodo a; a = new Nodo (elemento) ; if (queVacia()) { frente = a; : } else { } ultimo = a; nul. ultimo.enlace = a; // eliminar: suprime el elemento frente public TipoDeDato eliminarg() throws Exception TipoDevato aux; if (iquevacia()) Nodo a; a= frente; aux = frente.dato; frente = frente.enlace; a= null; Pilasycolas 507 ) else throw new Excep return aux; n(“Eliminar de una cola vacia"); // Libera todos los nodos de la cola public void borrarque() for (;frente!=nul1;) { Nodo n; n = frente; frente = frente.enlace; n = null; J/ acceso a la cola public TipoDeDato frenteQ() throws Exception { if (queVacia()) (ce throw new Exception(*irror: cola vacia"); } return (frente.dato) ; // verificacién del estado de la cola public boolean quevacia() { } return (frente == null); EJERCICIO 15.2. Una variacién del problema matemdtico llamado «problema de José» permite generar nimeros de la suerte. Se parte de una lista inicial de n ntimeros, esta lis- 1a se va reduciendo siguiendo el siguiente algoritmo: 1, Se genera un niimero aleatorio ni. 2. Sint <= n se quitan de la lisia los nimeros que ocupan las posiciones T,1+ nt,1+2*n1, ...; ntoma el valor del niimero de elementos que quedan en la lista. 3. Se vuelve al paso 1. 4, Sint > n findel algoritmo, los niimeros de la suerte son los que quedan en la lista, Fl problema se va a resolver utilizando Ia estructura cola. En primer lugar, se genera una lista de n iimeros aleatorios que se almacena en una cola, A continuacién se siguen los pasos del algoritmo, en cada pasada se eliminan los ¢lementos de la cola que estén en las posiciones (miltiplos de ni) #1 Estas posiciones i se pueden expresar matematicamente: i modulo nl = 1 Una ver. que termina el algoritmo se extraen los elementos que han quedado en Ia cola, que son los nimeros de la suerte. ji La clase Cola que se utiliza esta implementada con listas enlazadas. Bl tipo de dato de los elementos es entero, sin embargo para generalizar se definen de tipo Object, esto obliga a que al afiadir nuevos 508 — Programacién en JAVA 2 elementos se pasen como argumentos referencias a objetos Integer inicializados con cl mimero entero generado aleatoriamente. La clase Nodo se vuelve a escribir por clatidad, se podrfa utilizar el paquete i ListaGenerica del capitulo Listas enlazadas. 1/ paquete con la clase nodo i package colaGenerica; public class Nodo ( object dato; Nodo enlace; public Nodo (Object x) { i dato = x; enlace = null; } } HM paquete con la clase cola package colaGenerica; public class Cola ( private Nodo frente; private Nodo ultimo; public Cola() i { frente = ultimo = null; } public void insertarg (Object elemento) { Nodo a; a = new Nodo(elemento) ; if (queVacia()) i } else { } ultimo = a; } public Object eliminarQ()}throws Exception { Object aux; if (iqueVacia()) frente = a; ultimo.enlace Nodo a; a= frente; aux = frente.dato; frente = frente.enlace; - a= null; Pilasycolas 509 } else throw new Exception (*Bliminar de una cola vacia"); return aux; } public void borrarque() { for (;frente { null; ) Nodo nj; n = frente; frente = frente.enlace; n= null; } } public Object frenteQ() throws Exception { if (quevacia()) ide { throw new Exception("Brror: cola vacia"}; return (frente.dato) ; } public boolean queVacia() { return (frente | } } clase con el método main () , genera mimeros de la suerte null) ; import colaGenerica.*; import java.io.*; import java.util.Random; class NumerosSuerte { public static void main(String [} a) { int n, nl, n2, i; Integer nv; Cola q = new Cola(); Random x = new Random() ; try // némexo inicial de elementos de la lista n= 11 + rinextInt (49); // se generan n nfimeros aleatorios for (i=l; dicen; ist) { ny = new Integer (1+r-nextInt (101)) ; q.insertarg (nv) ; // se genera aleatoriamente el intervalo ni 510 Programacién en JAVA 2 ml = 1+r.nextInt (11); // se retiran de la cola elementos a distancia n1 while (nl <= n) { Object nt; n2= 0; // contador de elementos que quedan fal (isl; icen; i++) nt = q.eliminarg(); if Gi $ nl == 1) { ) System.out.print(*\n Se quita * + nt); else { q.ingertarg(nt); // se vuelve a meter en la cola n2++; } } = m2; ni = L+r.nextint (11) ; ) 7 System.out.printIn(\n\t Los mimeros de la suexte: “); fateh (ception © : System.out.println("Ha ocurrido la excepcién: “+ t); ) } private static void mostrarCola(Cola q) throws Exception ee (iq.quevacia()) : system.out.print (" * + q.eliminarg(}); ) } } 15.6. COLAS DE PRIORIDADES El término cola sugiere la forma en que ciertos objetos esperan la utilizacién de un determinado servicio. Por otro lado, el término prioridad sugiere que el servicio no se proporciona Gnicamente aplicando el concepto «primero en llegar, primero en ser atendido>, sino que cada objeto tiene asociada una prioridad ‘asada en criterio objetivo. Un aplicacién tipica de organizacién formando colas de prioridades es el sistema de tiempo compartid®, necesario para mantener una serie de procesos que esperan para que seam. ejecutados por el procesador. Cada proceso esté diseiiado de tal forma que lleva asociada una prioridad. El orden en que los elementos de una cola de prioridades son procesados sigue estas reglas: * Se elige la cola no vacfa que se corresponde con la mayor prioridad, + En la cola de mayor prioridad, los elementos se procesan segén el orden dé llegada: primero en entrar, primero en salir. eee Pitas yeolas = 511 15.6.1. Construccién de una cola de prioridades | La cola de prioridades se define en una clase con la representaci6n de la estructura en forma de una tabla o array de tantos elementos como prioridades vaya a haber, y los métodos que implementan las operaciones bisicas: crear, insertar, extraer y vaciar. El constructor de la clase realiza la operacién crear, establece el ntimero de prioridades e inicializa cada una de las colas. La operacién insertar afiade un nuevo objeto 7 de prioridad m a la estructura, siguiendo estos pasos: 2. Si existe, poner el objeto T al final de la cola | 1, Buscar la prioridad m en la tabla | 3. Sila prioridad m esta fuera del rango de prioridades, lanzar una excepci6i La operacién extzaex relira el objeto frente de la cola no vacia que tiene la méxima prioridad. Por tiltimo, vaciiar elimina todos los objetos que se encuentran en la estructura. a fete Ta Te Toe Tos Figura 15.10. Cola de prioridades, de 0 an prioridades, 15.6.2. Definicién de la clase cola de prioridades ‘Ademés de la clase CoLaPrioridad se utiliza la clase Cola, ésta se implementa con listas enlazadas, por lo que también es necesaria la clase Nodo; estas dos clases se encuentran en el paquete colaGenerica. Los elementos'de Ia estructura son objetos de la clase Tarea, que contiene una prioridad y una descripeisn. package colasDePrioridad; public class Tarea { int. prioridad; String dsc; public Tarea(int p) public setTarea(string k) { se = new string (k) ; } 512 Programacién en JAVA 2 public String descripcion() { t return dec; } // Gefinicién de la clase ColaPrioridades package colasDePrioridad; public class Colaprioridades { private int numprd; private Cola[] cpr; public ColaPrioridades (int maxprd) { numprd = maxprd; // crea tabla de colas; opr = new Cola{maxprd] ; } i public void insertar(Tarea f ) throws Exception { // prioridades en el rango 0 .. numprd-1 if (£.prioridad < numprd) { cpr [£.prioridad) .insertarQ(f) ; elae throw new Exception (*Objeto con prioridad fuera de rango”); } public Tarea extraer () throws Exception { int i= 0; Tarea d = do { 4£ (1 epe(i] .quevacia()) mull; 4 = cpr{i] .eliminarg() else Hi; }while ((isnumprd) e& (d=snull)); if (a f= null) return d; else : throw new Exception ("cola de prioridades vacia"); - public void vaciar() { for (int i = 0; i < numprd; ) epr [i++] .borrarQue() ; Pilasy cols 513 514 Programacién en JAVA 2 Pilasycolas 515

También podría gustarte