Está en la página 1de 10

REPÚBLICA BOLIVARIANA DE VENEZUELA

MINISTERIO DEL PODER POPULAR PARA LA EDUCACIÓN UNIVERSITARIA
UNIVERSIDAD BOLIVARIANA DE VENEZUELA
PROGRAMA DE FORMACIÓN DE GRADO EN
INFORMÁTICA PARA LA GESTIÓN SOCIAL

PROPUESTA PARA UN MANUAL DE APOYO EN LA ELECTIVA INTEGRAL
ESTRUCTURAS DINÁMICAS
COLAS

VERSION 1.0

Elaborado por: Prof. Juan Carlos Herrera

Una cola funciona como la línea en el cine: la primera persona a unirse a la parte trasera de la línea es la primera persona en llegar a la parte delantera de la línea y comprar un boleto. Fisrt-Output (FIFO). En informática una cola es una estructura de datos que es similar a una pila. así como las pilas. o paquetes de datos en espera de ser transmitidos por Internet. el último elemento insertado es el primero en ser eliminado (LIFO). También se utilizan para modelar situaciones del mundo real. En Gran Bretaña.Caracas. pero el equipo está haciendo brevemente algo más cuando se pulse una tecla. a excepción de que en una cola el primer elemento insertado es el primero en ser eliminado First-Imput. De esta manera. "cola" significa ponerse en la fila. Figura 1 Una cola de personas Las colas son utilizadas como herramienta para los programadores. esperan a que la impresora esté disponible. Hay varias colas que tranquilamente están haciendo su trabajo en sistema operativo de su computador (o la red). excepto que usted coloca los elementos en un extremo de la cola y los elimina de la otra. La última persona en la línea es la última persona que compra un billete (o si el espectáculo está vendido. Una cola también almacena los datos de pulsaciones de teclas al escribir en el teclado. los aviones esperando para despegar. Mayo de 2014 Colas y Prioridad Colas Una cola es similar a una pila. deja de comprar un billete). si usted está utilizando un procesador de textos. donde los trabajos de impresión. En esta clase aprenderá  Cómo funciona una cola  Cómo crear una cola en C++  Cómo funciona una cola de prioridad  Cómo crear una cola de prioridad en C++ La palabra cola es la palabra británica para línea (el tipo que espera en). Hay una cola de impresión. este espera en la cola hasta que 2 . En una pila. la combinación de teclas no se perderá. Una cola de prioridad es una cola especializada en la que los elementos son almacenados en orden. La Figura 1 muestra cómo se ve esto. tales como personas que esperaban en la fila de un banco.

front(0). //get value and incr front if(front == maxSize) //deal with wraparound front = 0.cpp //demonstrates queue #include <iostream> #include <vector> using namespace std. public: //-------------------------------------------------------------//constructor Queue(int s) : maxSize(s). y size (). int rear. int nItems. El uso de una cola garantiza las pulsaciones de teclado permanezcan en orden hasta que puedan ser procesadas.resize(maxSize). Todos los elementos son removidos y mostrados. nItems--. La sexta inserción invoca la función envolvente. class Queue { private: int maxSize. } //-----------------------------------------------------------int peekFront() //peek at front of queue { return queVect[front]. rear(-1). } //-------------------------------------------------------------void insert(int j) //put item at rear of queue { if(rear == maxSize-1) //deal with wraparound rear = -1.el procesador de textos tenga tiempo para leerlas. //one less item return temp. queVect[++rear] = j. vector<int> queVect. e inserta cuatro más. peek (). La salida es la siguiente: Listado 1 muestra el programa Queue. remove (). //one more item } //-----------------------------------------------------------int remove() //take item from front of queue { int temp = queVect[front++]. El programa main () crea una cola de cinco celdas. isEmpty (). } //-----------------------------------------------------------bool isEmpty() //true if queue is empty 3 .cpp //Queue. elimina tres elementos. nItems(0) { queVect. int front. Código C++ para una Cola El programa queue. //increment rear and insert nItems++. inserta cuatro elementos. isFull ().cpp cuenta con un clase Queue con las funciones miembros insert ().

Algunas implementaciones de colas no utilizan este dato miembro.insert(10). No mostramos esto en main ().remove().remove(). 60. } //-----------------------------------------------------------bool isFull() //true if queue is full { return (nItems==maxSize). esta alternativa se mostrará más tarde. while( !theQueue. theQueue. en maxSize-1. theQueue. (Por lo general es preferible colocar el chequeo de plenitud en la rutina insert (). return 0.) Normalmente. } //queue holds 5 items //insert 4 items //remove 3 items // (10. 4 . la parte inferior de la matriz. theQueue. la inserción implica incrementar rear e insertar en la celda en la que ahora apunta rear. theQueue. theQueue. theQueue.insert(60). 20.remove(). de modo que cuando tenga lugar el incremento rear pasará ser 0. pero normalmente llamaríamos insert () sólo después de llamar isFull () y obtener un valor de retorno de falso. 80) //end main() Hemos elegido un enfoque en el que los datos miembros de la clase Queue incluyen no sólo front y rear. sino también el número de ítems en la cola: nItems. Sin embargo. Finalmente nItems es incrementado.insert(40). La Función Miembro insert() La función de miembro insert () asume que la cola no está llena. } //-----------------------------------------------------------int size() //number of items in queue { return nItems. } cout << endl. theQueue. { return (nItems==0). } //-----------------------------------------------------------//end class Queue int main() { Queue theQueue(5). theQueue. Esto se hace mediante el establecimiento de rear a -1. theQueue.insert(80). 70. cout << n << “ “.insert(70). y causar una excepción para ser lanzada si se realizó un intento para insertar en una cola llena. theQueue. si rear está en el tope del arreglo (actualmente un vector).insert(30).}.remove(). 50. theQueue.insert(50).insert(20). 30) //insert 4 more items // (wraps around) //remove and display // all items //(40.isEmpty() ) { int n = theQueue. entonces debe envolver alrededor de la parte inferior del arreglo antes de que la inserción se lleve a cabo.

La cola puede entonces parecer estar llena y vacía al mismo tiempo. Finalmente. Implementación de la Clase Queue sin un contador de elementos La inclusión del dato miembro nItems en la clase Queue impone una ligera sobrecarga en las funciones miembro insert () y remove () en la que respectivamente deben incrementar. nItems es decrementado. Además. o construir esta comprobación de errores en remove ().La Función Miembro remove() La función miembro remove () asume que la cola no está vacía. Algunas implementaciones permiten mirar en la parte trasera del arreglo. y disminuir esta variable. o devolver su valor. las rutinas isEmpty (). Todos ellas se basan en el miembro de dato nItems. algunas implementaciones de colas se hacen sin un contador de elemento y se confía en los datos miembros front y rear para averiguar si la cola está vacía o llena y cuántos elementos hay en ella. este debe entonces ser envuelto alrededor de 0. pero pueden asumir estas mismas posiciones exactas cuando la cola está vacía. si esto coloca front más allá del final del arreglo. El valor de retorno se almacena temporalmente mientras esta posibilidad es comproda. Esta clase utiliza la implementación no-count. isFull () y size () proporcionan la información implícita en sus nombres. así. Usted debe llamar isEmpty () para asegurarse que esto es cierto antes de llamar a remove (). pero si usted está tratando con un gran número de inserciones y eliminaciones. La remoción siempre comienza con la obtención del valor de front y luego incrementar front. Listado 2 La Clase Queue sin nItems class Queue { private: int maxSize. Sin embargo. El listado 2 muestra una clase Queue que implementa este enfoque sin conteo. surge un problema extraño. Cuando se hace esto. Las Funciones Miembros isEmpty(). isFull(). Los punteros front y rear asumen ciertas posiciones cuando la cola está llena. como hemos visto. En consecuencia. isFull () y size () se vuelven sorprendentemente complicadas porque la secuencia de elementos puede estar rota o contiguas. La Función Miembro peek () La función miembro peek () es sencilla: devuelve el valor de front. respectivamente para comprobar si es 0. Este problema puede ser resuelto haciendo que el arreglo (vector) una celda más grande que el número máximo de elementos que puede ser colocado en ella. y size() Las funciones miembro isEmpty (). 5 . podría influir en el rendimiento. Esto podría no parecer una sanción excesiva. tales rutinas se llaman algo así como peekFront () y peekRear () o simplemente front () y rear (). ya sea maxSize.

rear(-1) { queVect. } //-------------------------------------------------------------int remove() //take item from front of queue { int temp = queVect[front++]. } //-------------------------------------------------------------- }. isEmpty () y size (). if(front == maxSize) front = 0. } //-------------------------------------------------------------//end class Queue Nótese la complejidad de las funciones miembros isFull (). Este enfoque NOCOUNT rara vez se necesita en la práctica. public: //-------------------------------------------------------------//constructor Queue(int s) : maxSize(s+1). else //broken sequence return (maxSize-front) + (rear+1). return temp. void insert(int j) //put item at rear of queue { if(rear == maxSize-1) rear = -1. } //-------------------------------------------------------------bool isEmpty() //true if queue is empty { return ( rear+1==front || (front+maxSize-1==rear) ). front(0). por lo cual no será discutido en detalle. 6 . queVect[++rear] = j.resize(maxSize).vector<int>(queVect). int front. } //-------------------------------------------------------------int size() //(assumes queue not empty) { if(rear >= front) //contiguous sequence return rear-front+1. } //-------------------------------------------------------------int peek() //peek at front of queue { return queVect[front]. int rear. } //-------------------------------------------------------------bool isFull() //true if queue is full { return ( rear+2==front || (front+maxSize-2==rear) ).

una cola de prioridad tiene una parte delantera y una parte trasera. algunas inserciones y eliminaciones podrían tomar mucho más tiempo que otras. la deque actua como una pila. Colas de prioridad Una cola de prioridad es una estructura de datos más especializada que una pila o una cola. los elementos se pueden insertar y extraer en un cola. y eliminarlos de cualquier extremo. este actúa como una cola. Sin embargo. por lo que el elemento con la clave más baja (o en algunas implementaciones la clave más alta) está siempre en la parte delantera. Si usted se restringe a insertLeft () y removeRight (). y los elementos son insertados en la parte trasera y son removidos desde la parte delantera. y removeLeft () y removeRight (). Esto se muestra en la Figura 2. Si se debe responder de inmediato (la compañía telefónica está a punto de desconectar la línea de módem). Sin embargo. Un deque proporciona una estructura de datos más versátil que una pila o una cola. Debido a la característica envolvente. Cada vez que el cartero entrega una carta. Nuevo término A deque es una cola de dos extremos. los elementos se ordenan por valor clave. usted inserta está en una pila (montón) de cartas pendientes en función de su prioridad. pero si se puede esperar una respuesta (una carta de su tía). va en la parte inferior. uno a la vez. en una cola de prioridad. y se utiliza a veces en las bibliotecas de contenedores de clases para ambos propósitos. va en la parte superior. Puede insertar elementos en cada extremo. no se utiliza tan a menudo como las pilas y colas. (o la pareja al lado). Cuando tenga tiempo para responder a su correo. así que no se va a explorar más a fondo aquí. Así como en la analogía de clasificación del correo se aplica a una cola de prioridad. Si usted se restringe a insertLeft () y removeLeft () (o sus equivalentes en la derecha).Eficiencia de las Colas Al igual que con una pila. 7 . Las funciones miembro pueden ser llamadas insertLeft () y insertRight (). usted comenzará tomando la carta de la parte superior (la parte frontal de la cola). Vamos a pasar de las colas a un segundo tema. Los elementos se insertan en la posición adecuada para mantener el orden. garantizando así que las cartas más importantes son respondidas primero. que es importante para esta clase. es una herramienta útil en un número sorprendente de situaciones. Al igual que una cola ordinaria. una estructura de datos relacionada llamada cola de prioridad. Sin embargo.

Listado 3 EL Programa priorityQ. if(nItems==0) queVect[nItems++] = item. Esta implementación sufre de inserción lenta.cpp //demonstrates priority queue #include <iostream> #include <vector> using namespace std. //////////////////////////////////////////////////////////////// class PriorityQ { //vector in sorted order. from max at 0 to min at size-1 private: int maxSize. j>=0.cpp //priorityQ. Además de proporcionar un acceso rápido al elemento con la clave más pequeña. Por esta razón. las colas de prioridad son. else { for(j=nItems-1. vector<double> queVect.resize(maxSize). //start at end. Así.Figura 2 Cola de Prioridad Al igual que las pilas y las colas. } //------------------------------------------------------------void insert(double item) { int j. aunque hay otras situaciones en las que la clave más alta tiene la más alta prioridad. asumiremos que ese es el caso en esta discusión. a menudo implementadas con una estructura de datos llamada pila. public: //------------------------------------------------------------PriorityQ(int s) : maxSize(s). nItems(0) { queVect. //insert at 0 //if items. Se utilizan de diversas maneras en ciertos sistemas informáticos. j--) { //constructor //insert item //if no items. también se quiere una cola de prioridad para proporcionar inserción bastante rápida. int nItems. el elemento con la clave más pequeña tiene la más alta prioridad. usted quiere tener acceso al elemento con el valor de la clave más bajo (que podría representar la forma más económica o la más corta de hacer algo). los programas pueden ser colocados en una cola de prioridad para que el programa de más alta prioridad sea el siguiente para recibir un intervalo de tiempo que permite que se ejecute. 8 . Un tanto arbitrariamente. En muchas situaciones. En un sistema operativo multitarea preferente. como hemos señalado antes. Código C++ para una cola de prioridad El código C++ para una cola de prioridad básica basada en un arreglo se muestra en el Listado 3. pero es más sencilla y es adecuada cuando el número de elementos no es alto o la velocidad de inserción no es crítica. por ejemplo. Sin embargo. vamos a mostrar una cola de prioridad implementada con un simple arreglo. las colas de prioridad se utilizan a menudo como herramientas del programador.

//////////////////////////////////////////////////////////////// int main() { PriorityQ thePQ(5). 9 . } } //------------------------------------------------------------double remove() { return queVect[--nItems].insert(10).insert(50). } //if new item larger. usted debe comprobar esta posibilidad con isFull () antes de usar insert (). 50 Análisis La función miembro insert () comprueba si hay algunos elementos. y luego los retiramos y los mostramos.insert(30). //done shifting //end for //insert it //end else (nItems > 0) //end insert() //remove minimum item //peek at minimum item //true if queue is empty //true if queue is full //end class PriorityQ //priority queue. //shift upward //if smaller. } //------------------------------------------------------------bool isEmpty() { return (nItems==0). la función se inicia en la parte superior del arreglo y los cambios de los elementos existentes van hacia adelante hasta encontrar el lugar donde el nuevo elemento deberá ir. size 5 //unsorted insertions //sorted removals //end while //end main() En main () insertamos cinco elementos en orden aleatorio. 40. thePQ. este se inserta en el índice 0. } queVect[j+1] = item. cout << item << “ “. while( !thePQ.remove(). 30. //10. thePQ.insert(40). } //------------------------------------------------------------double peekMin() { return queVect[nItems-1]. return 0. 30. por lo que la salida es 10. Tenga en cuenta que si hay alguna posibilidad de que la cola de prioridad está llena. else break.isEmpty() ) { double item = thePQ.if( item > queVect[j] ) queVect[j+1] = queVect[j]. 20. } //------------------------------------------------------------}. El elemento más pequeño siempre se elimina en primer lugar. nItems++. } //------------------------------------------------------------bool isFull() { return (nItems == maxSize). thePQ. 20. De lo contrario. 40. 50 } cout << endl. si no. thePQ.insert(20). Luego se inserta el nuevo elemento e incrementa nItems. thePQ.

como hemos señalado. Las funciones miembro isEmpty () y isFull () comprueban si nItems es 0 o maxSize.  Una cola puede ser implementada como una cola circular. ya que. Referencias bibliográficas7 C++ For Artists: The Art. sólo un elemento de datos se puede acceder inmediatamente.  En estas estructuras de datos. que se basa en un arreglo en la que los índices se envuelven alrededor del final del arreglo al comienzo. front está siempre a nItems-1 y rear está siempre a 0. a veces el más grande).El miembro de datos front y rear no son necesarios. ya que estaban en la clase Queue. La función miembro peekMin () es similar. excepto que no disminuye nItems. se ha aprendido lo siguiente:  Las colas y colas de prioridad. respectivamente. Resumen En esta clase.  Las operaciones de cola más importantes son insertar un elemento en la parte posterior de la cola y quitar un elemento de la parte delantera de la cola.  Una cola de prioridad permite el acceso a los elementos más pequeños (o. así como las pilas. Philosophy.  Las operaciones importantes de colas de prioridad son insertar un elemento en forma ordenada y retirar un elemento con la clave más pequeña.  Una cola permite el acceso al primer elemento que se inserta. and Science of Object-Oriented Programming by Rick Miller (2003) 10 . son estructuras de datos que por lo general se utilizan para simplificar algunas operaciones de programación. La función miembro remove () es simplemente la misma: decrementa nItems y devuelve el elemento de la parte superior del arreglo.