Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Albert)
COLAS
12
11.1 Fundamentos
Las colas son secuencias de elementos caracterizadas porque las operaciones de insercin y
borrado se realizan sobre extremos opuestos de la secuencia. La insercin se produce en el
"final" de la secuencia, mientras que el borrado se realiza en el otro extremo, el "inicio" de la
secuencia.
Las restricciones definidas para una cola hacen que el primer elemento que se inserta en ella
sea, igualmente, el primero en ser extrado de la estructura. Si una serie de elementos A, B, C,
D, E se insertan en una cola en ese mismo orden, entonces los elementos irn saliendo de la
cola en el orden en que entraron. Por esa razn, las colas tambin se conocen con el nombre
de listas FIFO (First In First Out, el primero que entra es el primero que sale).
Estructura Cola
A B C D E F ...
Borrado Insercin
Las colas, al igual que las pilas, resultan de aplicacin habitual en muchos problemas
informticos. Una aplicacin comn de las colas se da
es la organizacin de tareas de un ordenador. En general, un ordenador posee un nmero
reducido de unidades de proceso (1 o 2 CPUs) y, sin embargo, debe ejecutar muchos
programas simultneamente. Para poder hacer esto, los programas que se deben ejecutar en
el ordenador son almacenados en una cola, para ir procesando secuencialmente todos los
trabajos. Cuando el ordenador recibe el encargo de realizar una tarea, sta es almacenada al
final de la cola de trabajos. En el momento que la tarea que estaba realizando el procesador
acaba, ste selecciona la tarea situada al principio de la cola para ser ejecutada a continuacin.
Todo esto suponiendo la ausencia de prioridades en los trabajos. En caso contrario, existir
una cola para cada prioridad. Del mismo modo, es necesaria una cola, por ejemplo, a la hora
de gestionar eficientemente los trabajos que deben ser enviados a una impresora (o a casi
cualquier dispositvo conectado a un ordenador). De esta manera, el ordenador controla el
envio de trabajos al dispositivo, no enviando un trabajo hasta que la impresora no termine con
el anterior.
Anlogamente a las pilas, es necesario definir el conjunto de operaciones bsicas para
especificar adecuadamente una estructura cola. Estas operaciones seran:
- Crear una cola vaca.
- Determinar si la cola est vaca, en cuyo caso no es posible eliminar elementos.
- Acceder al elemento inicial de la cola.
- Insertar elementos al final de la cola.
- Eliminar elementos del inicio de la cola.
Pg. 1
Tema 12. Colas
Al igual que realizamos con las pilas, haremos una declaracin un poco ms formal de estas
operaciones y los axiomas que las caracterizan:
Estructura
Cola ( Valor ) {* Valor ser el tipo de datos que podremos guardar
en la cola *}
Operaciones
CrearCola ( ) Cola
Encolar ( Cola , Valor ) Cola
Desencolar ( Cola ) Cola
PrimeroCola ( Cola ) Valor
ColaVacia ( Cola ) Lgico
Axiomas
q Cola, x Valor se cumple que:
ColaVacia ( CrearCola ( ) ) cierto
ColaVacia ( Encolar ( q, x ) ) falso
Desencolar ( CrearCola ( ) ) error
Desencolar ( Encolar ( q, x ) )
{ ColaVacia si ColaVacia q = cierto
Encolar Desencolar q , x sino
PrimeroCola ( CrearCola ( ) ) error
PRIMERO_COLA ( Encolar ( q, x ) )
{x si ColaVacia q = cierto
PrimeroCola q sino
Estos axiomas vienen a decir bsicamente lo siguiente:
Cuando se crea una cola (CrearCola) est vaca, mientras que una cola en la que, al menos,
hemos puesto un elemento no lo est.
Tanto intentar eliminar un elemento, como consultar el primer elemento de una cola recin
creada, produce un error.
Y finalmente, la consulta de una cola en la que hemos insertado un nuevo elemento x,
devolver x si la cola estaba vaca, o el primero de la cola si la cola ya contena otros
elementos.
Pg. 2
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
class Cola
{
public:
Cola ();
bool Encolar (Valor);
bool Desencolar ();
bool PrimeroCola (Valor &);
bool ColaVacia ();
private:
//Todava por definir
};
private:
typedef Valor Vector[MAX];
Vector datos;
int ini, fin;
};
Sea una cola q cuyos elementos son (a, b, c, d, e), siendo a su primer elemento y e el ltimo.
La representacin grfica de la implementacin de q mediante un array, podra ser:
q = (a, b, c, d, e)
Pg. 3
Tema 12. Colas
0 1 2 3 4 MAX-1
a b c d e ...
inicio fin
Hay que tener en cuenta que los extremos de la secuencia se pueden ir desplazando a medida
que se realizan operaciones sobre la cola. As, por ejemplo, aadir (Encolar) el elemento f a
la cola q implicar desplazar el ndice fin a la siguiente posicin del array:
q.Encolar ('f')
0 1 2 3 4 5
a b c d e f ...
inicio fin
q.Desencolar ()
0 1 2 3 4 5
a b c d e f ...
inicio fin
Las posiciones de inicio y fin siempre delimitan el conjunto de valores que forman parte
de la cola, con independencia de los datos contenidos en otras posiciones del array. As por
ejemplo, la figura anterior nos est diciendo que la cola q est formada por los elementos (b,
c, d, e, f).
Tambin se podra seguir el criterio de mantener siempre el inicio de la cola en la posicin 0
del array, pero eso implicara tener que desplazar todos los elementos de la cola una posicin
hacia la izquierda cada vez que se eliminase un elemento. Este proceso sera muy poco
eficiente, puesto que tendra un coste lineal con el nmero de elementos almacenados en la
cola. Por esa razn, no vamos a tratar esta posibilidad.
Un problema que tiene la representacin que estamos presentando es determinar la condicin
de cola llena Cmo determinar que no espacio para almacenar ms elementos? Un visin
Pg. 4
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
simplista nos hara pensar que la cola est llena cuando el ndice fin apunta a la ltima
posicin del vector (fin == MAX-1). En realidad, esta condicin no indica necesariamente
que los elementos de la cola estn ocupando todas las posiciones del array, ya que es posible
que exista espacio libre, por haber ido borrando elementos, en las primeras posiciones del
array.
Un aprovechamiento ms eficiente del espacio reservado para los datos se obtiene
interpretando el array donde guardamos la informacin contenida en la cola como si fuese
circular. De esa manera, cuando se de el caso fin == MAX-1, ser posible insertar nuevos
elementos en la cola si los primeros elementos del array estn libres.
Para trabajar de forma sencilla con esta representacin ser conveniente definir una operacin
auxiliar que nos lleve de un ndice a su siguiente dentro de la nueva secuencia circular de
ndices. Esta operacin se limitar a incrementar el ndice si ste es menor que MAX-1 y a
volver a empezar en cero si se alcanza el valor MAX-1.
int Cola::Siguiente (int i)
{
return ( (i + 1) % MAX );
}
o lo que es lo mismo:
int Cola::Siguiente (int i)
{
if ( i == (MAX-1) )
return (0);
else
retrun ( i+1 );
}
Con esta interpretacin la condicin de cola llena se dar cuando inicio == Siguiente
(fin), es decir, el inicio de la cola est a continuacin del final. Por ejemplo:
q = (a, b, c, d, e, f, g)
0 1 2 3 4 5 6
f g a b c d e
fin inicio
Esta forma de representacin de una cola suele ser la ms habitual y recibe el nombre de cola
circular.
Pg. 5
Tema 12. Colas
0 1 2 3 4 5 6
? g ? ? ? ? ?
inicio
fin
0 1 2 3 4 5 6
? ? ? ? ? ? ?
fin inicio
Entonces, se cumple que inicio == Siguiente (fin) La misma condicin que se
cumple cuando la cola est llena!
Para evitar esta ambigedad y poder establecer condiciones diferentes para las situaciones de
cola llena y cola vaca, se establece que el ndice inicio se retrase una posicin respecto al
primer elemento de la cola. Siempre apunta a la posicin anterior al primer elemento y nunca
se utiliza la posicin de inicio para almacenar un elemento (se desaprovecha una posicin del
array). Esto hace que la situacin cuando la cola est llena sea:
q = (a, b, c, d, e, f)
0 1 2 3 4 5 6
e f a b c d
fin inicio
Pg. 6
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
0 1 2 3 4 5 6
inicio fin
0 1 2 3 4 5 6
inicio
fin
Ahora, la condicin cambia. La cola est vaca cuando inicio == fin.
Como ya tenemos claro el esquema que se puede seguir, vamos a proceder a la
implementacin de las operaciones:
Operacin CrearCola
La creacin de la cola se realizar mediante el constructor por defecto. La tarea que deber
realizar ser establecer un estado inicial en el que no existen elementos en la cola. Es decir,
inicio y fin deben coincidir:
Cola::Cola ()
{
inicio = 0;
fin = 0;
}
Se podra haber fijado cualquier posicin, como el tratamiento del array va a ser circular no
importa en que posicin se empiece a introducir elementos.
Pg. 7
Tema 12. Colas
Operacin ColaVacia
Esta operacin permitir determinar si la estructura tiene o no elementos almacenados. Como
se ha dicho anteriormente, la cola estar vaca cuando inicio y fin coincidan:
bool Cola::ColaVacia ()
{
return (inicio == fin);
}
Operacin Encolar
La operacin, aplicada sobre un cola y un valor, almacena el valor al final de la cola. Esta
operacin est restringida por el tipo de representacin escogido. En este caso, la utilizacin
de un array implica que se tiene un nmero mximo de posibles elementos en la pila, por lo
tanto, es necesario comprobar, previamente a la insercin, que realmente hay espacio en la
estructura para almacenar un nuevo elemento. Con est consideracin, el algoritmo de
insercin sera:
bool Cola::Encolar (Valor x)
{
bool ok = true;
if ( inicio == Siguiente(fin) )
ok = false; //Cola llena
else
{
fin = Siguiente (fin);
datos[fin] = x;
}
return (ok);
}
Operacin Desencolar
La operacin de borrado elimina de la estructura el elemento situado en la primera posicin
(despus de inicio). Eliminar un elemento de la cola consiste fundamentalmente en
desplazar inicio a la siguiente posicin. Puesto que no es posible eliminar fsicamente los
elementos de un array, lo que se hace es dejar fuera del rango vlido de elementos al primero
de ellos.
bool Cola::Desencolar ()
{
bool ok = true;
if ( inicio == fin )
ok = false; //Cola vaca
Pg. 8
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
else
inicio = Siguiente (inicio);
return (ok);
}
Operacin PrimeroCola
La operacin de consulta permite conocer el elemento almacenado en la cima de la pila,
teniendo en cuenta que si la pila est vaca no es posible conocer este valor.
bool Cola::PrimeroCola (Valor & x)
{
bool ok;
if (inicio == fin)
ok = false; //Cola vaca
else
{
x = datos[siguiente (inicio)];
ok = true;
}
return (ok);
}
a
d
c
d
e
Pg. 9
Tema 12. Colas
Pg. 10
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
Operacin ColaVacia
Necesita verificar si el puntero a inicio ( o fin) referencia algn nodo.
bool Cola::ColaVacia ()
{
return (inicio == NULL);
}
Operacin Encolar
Es preciso reservar memoria para cada nuevo elemento que se desee aadir a la cola, puesto
que no hay espacio reservado para l a priori. Adems de sto, es preciso que el nuevo
elemento se enlace adecuadamente con el resto de elementos de la cola. El nuevo nodo
siempre ser el ltimo de la cola y se aadir detrs de fin. Adems, hay que tener en cuenta
que este elemento tambin ser el primero en el caso en que la cola estuviese vaca.
void Cola::Encolar (Valor x)
{
Puntero p_aux;
Operacin Desencolar
En una estructura dinmica es posible liberar la memoria reservada previamente si ya nos es
necesaria. En este caso, cuando se desapila un elemento, es posible liberar la memoria
asociado al nodo que ocupa en la pila. Luego, adems de avanzar la cima para que el elemento
quede fuera de la pila se debe liberar la memoria que ocupaba. La funcin sera la siguiente:
bool Cola::Desencolar ()
{
bool ok;
Puntero p_aux;
if (inicio == NULL)
Pg. 11
Tema 12. Colas
ok = false;
else
{
p_aux = inicio;
inicio = inicio->sig;
if (inicio == NULL)
fin = NULL;
delete p_aux;
ok = true;
}
return (ok);
}
Operacin PrimeroCola
Esta operacin debe devolver el valor almacenado la primera posicin de la cola. En este caso,
la informacin almacenada en el campo info del nodo.
bool Cola::PrimeroCola (Valor & x)
{
bool ok;
if (inicio == NULL)
ok = false;
else
{
x = inicio->info;
ok = true;
}
return (ok);
}
Pg. 12
Alg. y Estr. Datos-I / Fund. Progr.-II (R. Ferrs, J. Albert)
La funcin Copiar ser prcticamente idntica a la construidas para pilas, puesto que el
proceso a realizar el mismo:
void Cola::Copiar (const Cola& c)
{
Puntero p_aux, dup;
Vaciar();
p_aux = c.inicio;
while ( (p_aux != NULL) && ok )
{
dup = new Nodo;
dup->info = p_aux->info;
dup->sig = NULL;
if (inicio == NULL)
inicio = dup;
else
fin->sig = dup;
fin = dup;
p_aux = p_aux->sig;
}
}
void Cola::Vaciar()
{
while (Desencolar());
}
Operador asignacin
El operador asignacin tiene el mismo problema que la copia de objetos cuando se manejan
punteros. Se trata tambin de copiar un objeto en otro. Para que se pueda utilizar de manera
correcta el operador asignacin sobre elementos de la clase pila implementada con punteros es
preciso realizar lo que se llama una sobrecarga del operador asignacin (=). Esto significa
especificar cmo se debe realizar la asignacin de objetos de esta clase. La implementacin de
la sobrecarga del operador = (operator=) sera idntica a la del operador de copia (de ah la
conveniencia de haber definido la funcin Copiar).
const Cola& Cola::operator= (const Cola& c)
{
Copiar(c)
return (*this);
}
Pg. 13
Tema 12. Colas
Destructor
El destructor de una clase es nico, a diferencia del constructor, y no tiene argumentos. Su
nombre es el mismo de la clase, pero precedido del smbolo ~. Suponiendo que existe la
funcin auxiliar Vaciar que se ha utilizado ya en la funcin Copiar, el destructor de la clase
Cola tendra la siguiente forma:
Cola::~Cola ()
{
Vaciar();
}
Pg. 14