Capitulo III Colas

Transcripción

Capitulo III Colas
Capitulo III
Colas
El camino del Tigre
Un hombre caminaba por el bosque cuando vió una zorra lisiada. "¿Cómo hará para alimentarse?", pensó.
En ese momento, se acercó un tigre, con un animal entre los dientes. Sació su apetito, y le dejó a la zorra lo que había
sobrado. "Si Dios ayuda a la zorra, también me va a ayudar", reflexionó.
Volvió a su casa, se encerró en ella, y se quedó esperando que los Cielos le proveyeran de alimento. Nada pasó.
Cuando ya se estaba quedando demasiado débil para salir a trabajar, se le apareció un ángel.
- ¿Por qué decidiste imitar a la zorra lisiada? -preguntó el ángel.
- ¡Levántate, toma tus herramientas, y sigue el camino del tigre!
de Paulo Coelho
3.1. Introducción
La estructura de datos "cola" también llamada "Queue", es un tipo de datos abstracto
"TDA". Una cola TDA permite a una lista de cosas ser removidos en el orden en que
fueron almacenados.
Una cola es una lista de elementos en la que éstos se introducen por un extremo y se
eliminan por otro. Los elementos se eliminan en el mismo orden en el que se insertaron.
Por lo tanto, el primer elemento que entra a la cola será el primero en salir. Debido a esta
característica, las colas también reciben el nombre de estructuras FIFO (First In, First Out:
Primero en entrar, primero en salir).
Las colas en computación son muy similares a las colas de la vida real.
Ejemplos:
a. cola de clientes esperando pagar en una caja de supermercado
b. cola de clientes esperando ser atendidos por algún cajero en un banco
c. cola de procesos esperando ser ejecutados por una CPU
Al igual que la pila, la cola es una estructura de datos dinámica, pero puede ser
Programación II
Ingenieria de Sistemas
47
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
representado en forma estática (arreglos).
3.2.
Características
•
Todos los elementos de la cola son del mismo tipo.
•
Existe un orden de elementos ya que es una estructura lineal, pero los elementos
no están ordenados por su valor sino por orden de introducción en la cola.
•
Existen dos extremos en la estructura lineal cola, el frente y el final de la cola.
•
Sólo se puede acceder y eliminar al dato que está en el frente de la cola.
•
Sólo se puede añadir información al final de la cola.
3.3. Representación De Las Colas
Al igual que las pilas, las colas no existen como estructuras de datos estándares en los
lenguajes de programación. Las colas pueden representarse mediante el uso de:
•
Arreglos
•
Listas Enlazadas.
Como en el caso de las pilas, utilizaremos arreglos. Debe definirse el tamaño máximo
para la cola y dos variables auxiliares. Una de ellas para que guarde la posición del primer
elemento de la cola (FRENTE) y otra para que guarde la posición del último elemento de
la cola (FINAL). En el ejemplo siguiente se muestra una representación de una cola en la
cual se ha insertado cuatro elementos: 11, 22, 33 y 44, en ese orden.
El elemento 11 está en el frente ya que fue el primero que entró en la cola. Mientras que
el elemento 44, que fue el último en entrar, está en el FINAL de la cola.
MAX=6
Ejemplo: sea una cola Q de números enteros:
Q=
11
1
22
2
33
3
Frente
44
4
5
6
Final
3.4. Estructura de Una cola
Implementamos en el lenguaje C++ la estructura de una cola, y para ello utilizaremos
REGISTROS como sigue:
Programación II
Ingenieria de Sistemas
48
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
#define MAX 40
Struct COLA
{
int Q[MAX];
int FRENTE;
int FINAL;
//OPERACIONES
void INSERTAR(int elem);
void ELIMINAR (void);
void CREAR(void);
void IMPRIMIR (void);
};
3.5. Operaciones Con Colas
Análogamente a las pilas, es necesario definir el conjunto de operaciones básicas para
especificar adecuadamente una estructura cola. Estas operaciones serían:
•
Crear una cola vacía.
•
Insertar elementos al final de la cola.
•
Eliminar elementos al inicio de la cola.
•
Imprimir los elementos de una cola
Para determinar correctamente cada una de estas operaciones, es necesario especificar
un tipo de representación para las colas.
Como se puede notar, una cola tiene dos operaciones primitivas:
•
Insertar un elemento en la cola (Add/Insert)
•
Eliminar un elemento de la cola (Remove)
y operaciones auxiliares:
•
Crear cola
•
Imprimir Cola
Crear cola:
Esta operación consistirá en definir la variable de tipo array que permitirá almacenar la
información y las variables que apuntarán a los extremos de la
void COLA::CREAR (void)
{
FRENTE = 0;
FINAL = 0;
cout<< “ \n La cola ha sido creada “;
getch();
}
Programación II
Ingenieria de Sistemas
49
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
Insertar un elemento en la cola:
Debido a la implementación estática de la estructura cola es necesario determinar si
existen huecos libres donde poder insertar antes de hacerlo. Esto puede hacerse de
varias formas:
void COLA ::INSERTAR (int elem)
{
//este procedimiento inserta el elemento ELEM al final de la cola V
// FRE y FIN son los punteros que indican respectivamente el inicio y
//fin de la cola. MAX es el máximo número de elementos que puede
//almacenar la cola
if (FINAL < MAX) // verifica si hay espacio libre
{
FINAL = FINAL + 1;
Q [FINAL] = elem;
If (FINAL = = 1)
FRENTE = 1;
}
else
{
cout<<”cola llena…”;
exit(1);
}
}
Eliminar un elemento de la cola:
Como vera la eliminación no borra nada 'físicamente', sólo se encarga de actualizar el
puntero 'frente' en una posición y devolver el valor x como mucho, aunque esto último no
sea estrictamente necesario. Aunque esa posición aun contenga datos será considerada
como vacía a efectos del otro puntero 'final'.
int COLA ::ELIMINAR (void)
{ // elimina el primer elemento de la Cola Q, y lo almacena en ELEM. FRENTE
// y FINAL son los punteros que indican respectivamente el inicio y fin de
// la cola V.
int elem ;
if ( FRENTE != 0) // verifica que la cola no este vacia
{
elem = Q[FRENTE];
if ( FRENTE = = FINAL ) //si hay un solo elemento
{
FRENTE = 0;
FINAL = 0;
}
else
FRENTE = FRENTE +1 ;
}
else{
cout<<” COLA VACIA ”;
exit (1);
}
return(elem);
}
Programación II
Ingenieria de Sistemas
50
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
Imprimir una cola
El siguiente procedimiento permite imprimir los elementos de la cola:
void COLA::IMPRIMIR(void)
{
for (int i = FRENTE ; i<=FINAL; i++)
cout<< “\n “ << Q[i];
}
Ejercicio
A continuación implementamos el código correspondiente al programa de manejo de
colas lineales
#include <iostream.h>
#include <conio.h>
#include <process.h>
#define MAX 40
Struct COLA
{
int Q[MAX];
int FRENTE;
int FINAL;
//OPERACIONES
void INSERTAR(int elem);
void ELIMINAR (void);
void CREAR(void);
void IMPRIMIR (void);
};
void COLA::CREAR (void)
{
FRENTE = 0;
FINAL = 0;
cout<< “ \n La cola ha sido creada “;
getch();
}
void COLA ::INSERTAR (int elem)
{
//este procedimiento inserta el elemento ELEM al final de la cola V
// FRE y FIN son los punteros que indican respectivamente el inicio y
//fin de la cola. MAX es el máximo número de elementos que puede
//almacenar la cola
if (FINAL < MAX) // verifica si hay espacio libre
{
FINAL = FINAL + 1;
Q [FINAL] = elem;
If (FINAL = = 1)
FRENTE = 1;
}
else
{
cout<<”cola llena…”;
exit(1);
}
Programación
II
}
Ingenieria de Sistemas
51
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
int COLA ::ELIMINAR (void)
{ // elimina el primer elemento de la Cola Q, y lo almacena en ELEM. FRENTE
// y FINAL son los punteros que indican respectivamente el inicio y fin de
// la cola V.
int elem ;
if ( FRENTE ! = 0) // verifica que la cola no este vacia
elem = Q[FRENTE];
if ( FRENTE =
{
FRENTE
FINAL
}
else
FRENTE = FRENTE
= FINAL) //si hay un solo elemento
= 0;
= 0;
+1 ;
else{
cout<<” COLA VACIA
exit (1);
”;
}
return(elem);
}
void COLA::IMPRIMIR(void)
{
for (int i = FRENTE ; i<=FINAL; i++)
cout<< “\n “ << Q[i];
}
//PROGRAMA PRINCIPAL
void main (void)
{
COLA Q1 ;
int e, n ;
Q1.CREAR( ) ;
cout<< « \n cuantos elementos desea introducir a la cola ? “; cin>> n;
for (int i=1 ; i<=n; i++)
{
cout<<” \n Ingrese elemento ”;
cin >> e;
Q1.INSERTAR(e);
}
cout<<”\n\n los elementos de la cola son : “;
Q1.IMPRIMIR( );
getch( );
}
Programación II
Ingenieria de Sistemas
52
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
3.6. Colas Circulares
Para hacer un uso más eficiente de la memoria disponible se trata a la cola como una
estructura circular. Es decir, el elemento anterior al primero es el último. En la figura 3.1
se muestra la representación de una cola circular.
9
Ejemplo
8
33
1
45
22
85
2
Final
7
Frente
67
6
3
4
5
Para el siguiente ejemplo (a), en el cual ya no es posible adicionar elementos siguiendo la
anterior estructura, se propone la alternativa (b):
1
2
3
D
E
4
5
Frente
5
Final
(a)
F
1
2
3
Final
(b)
D
E
4
5
5
Frente
(a)
Programación II
Ingenieria de Sistemas
53
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
3.7. Operaciones Con Colas Circulares
Las operaciones basicas con colas circulares son: insertar, eliminar y mostrar una cola
circular.
void COLA :: INSERTA_CIRCULAR(int e)
{
if ( ( ( FINAL == MAX ) && (FRENTE == 1
) ) || ( FRENTE == FINAL +1 ) )
{
cout<<"\n\t..........cola llena.........";
exit(1);
}
else
{
if ( FINAL == MAX )
FINAL = 1;
else
if ( FRENTE == 0 )
{
FRENTE =1;
FINAL =1;
}
else
FINAL = FINAL +1;
Q[ FINAL ] = e ;
}
}
int COLA ::ELIMINA_CIRCULAR (void )
{
int e;
if(FRENTE ==0) {
cout<<"............cola vacia.......";
exit(1);
}
else
{
e= Q[FRENTE] ;
if ( FRENTE == MAX ) FRENTE=1;
else
if(FRENTE ==FINAL)
{
FRENTE = 0;
FINAL = 0;
}
else FRENTE = FRENTE +1;
}
return( e );
}
void COLA ::COLA_IMPRIME_CIRCULAR ( void)
{
while (FRENTE ! = FINAL )
{
cout<< Q[ FRENTE ];
if (FRENTE == MAX)
FRENTE =1 ;
FRENTE = FRENTE + 1 ;
}
cout<< “\n ”<<Q [FRENTE];
getch();
}
EJERCICIO:
Eliminar el primer elemento impar de una cola circular Q de números enteros
Programación II
Ingenieria de Sistemas
54
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
void ELI_IMPAR ( COLA Q)
{
int e, sw = 0 ;
int m = Q.FINAL + 1 ;
while (Q.FRENTE ! = m && sw == 0 )
{
e = Q.ELIMINA_CIRCULAR() ;
if ( e % 2 != 0)
sw = 1;
else
Q.INSERTA_CIRCULAR(e);
}
Q.IMPRIME_CIRCULAR();
getch();
}
3.8.
Aplicación De Pilas Y Colas
Hasta ahora se ha tratado solamente con la representación en memoria y manipulación
de una única pila o cola. Se han visto dos representaciones secuenciales eficientes para
dichas estructuras. Sin embargo, en ocasiones, es preciso representar varias estructuras
utilizando el mismo espacio de memoria.
Supongamos que seguimos transformando las estructuras de datos en representaciones
Secuenciales, tipo array. Si sólo hay que representar dos pilas sobre un mismo array
A[1..n], la solución puede resultar simple. Se puede hacer crecer las dos pilas partiendo
desde los extremos opuestos del array, de forma que A[1] será el elemento situado en el
fondo de la primera pila y A[n] el correspondiente para la segunda pila. Entonces, la pila 1
crecerá incrementando los índices hacia A[n] y la pila 2 lo hará decrementando los índices
hacia A[1]. De esta manera, es posible utilizar eficientemente todo el espacio disponible.
Si se plantea representar más de dos pilas sobre ese mismo array A, no es posible seguir
la misma estrategia, ya que un array unidimensional sólo tiene dos puntos fijos, A[1] y
A[n], y cada pila requiere un punto fijo para representar el elemento más profundo.
Cuando se requiere representar secuencialmente más de dos pilas, por ejemplo m pilas,
es necesario dividir en m segmentos la memoria disponible, A[1..n], y asignar a cada uno
de los segmentos a una pila. La división inicial de A[1..n] en segmentos se puede hacer
en base al tamaño esperado de cada una de las estructuras. Si no es posible conocer esa
información, el array A se puede dividir en segmentos de igual tamaño. Para cada pila i,
se utilizará un índice f(i) para representar el fondo de la pila i y un índice c(i) para indicar
Programación II
Ingenieria de Sistemas
55
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
dónde está su tope. En general, se hace que f(i) esté una posición por debajo del fondo
real de la pila, de forma que se cumpla la condición f(i)=c(i) si y solamente si la pila i está
vacía.
EJERCICIOS
1.
Realizar un programa para eliminar los elementos positivos de una cola.
2.
Escribir un programa para intercambiar con su adyacente los elementos de una
cola
3.
4.
Utilizando colas circulares resuelva el problema de Josefo.
Con colas circulares un procedimiento para manejo de colas de prioridades.
5.
Utilice una estructura de cola para simular el movimiento de clientes en una cola
de espera de un banco.
6.
7.
8.
Escriba un procedimiento para insertar un elemento en una doble cola.
Escriba un programa que invierta los elementos de una cola.
Escriba un procedimiento para eliminar un elemento de una doble cola.
9.
Sea C una cola circular de 6 elementos. Inicialmente la ola esta vacía
(FRENTE=FINAL=0). Dibuje el estado de Cluego de realizar cada una de las
siguientes operaciones:
a. Insertar los elementos: A,B y C
b. Eliminar el elemento: A
c. Insertar los elementos: D, E y F
d. Insertar el elemento: G
e. Insertar el elemento: H
f.
Eliminar los elementos: B y C
¿Con cuántos elementos qudó C?
¿Hubo algún caso de error (Desbordamiento o subdesbordamiento)?. Explique.
4
Implemente las operaciones de Colas Simples.
Sugerencia: Use el siguiente programa principal
void main()
{int C[MAX],fr,fi,opcion,d;
for(;;)
{ cout<<" OPERACIONES CON TDAs COLA"<<endl;
Programación II
Ingenieria de Sistemas
cout<<"1. Crear
cout<<"2. Insertar
"<<endl;
"<<endl;
cout<<"3. Eliminar
"<<endl;
56
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia
cout<<"4. Mostrar
cout<<"5. Salir
"<<endl;
"<<endl;
cin>>opcion;
switch(opcion){
case 1: inicializaC(&fr,&fi);
break;
case 2: cout<<"Ingrese un dato -> ";
cin>>d;
insertaC(C,fi,d,&fi);
break;
case 3: eliminaC(C,fr,fi,&d,&fr);
cout<<"Se eliminó el -> "<<d;
break;
case 4: mostrarC(C,fr,fi);
break;
case 5: cout<<"Fin de programa !!!";
exit(0);
break;
}}}
5
Escriba un programa que cree una pila a partir de una cola.
6
Ecriba un programa que permita animar las operaciones de colas gráficamente para
una empresa de autos.
7
Implemente las operaciones de Colas Circulares.
Programación II
Ingenieria de Sistemas
57
Lic. Katya Pérez Martínez
Lic. Gladys Chuquimia

Documentos relacionados