Está en la página 1de 21

Universidad Mariano Gálvez

Facultad de Ingeniería en Sistemas de Información


Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

DOCUMENTO DE PILAS COLAS

PILAS, COLAS Y DOBLE COLA (STACK, QUEUE, DQUEUE). En programación, el uso de listas
es una práctica tan extendida que lenguajes tales como (por ejemplo) Java, Python y C++
soportan los mecanismos necesarios para trabajar con estructuras de: Vectores, Pilas, Colas,
Listas, etc. En C++, los programadores que usen Dev-Cpp ( Bloodshed.software -Dev-C++ ) pueden
aprovechar las ventajas que ofrecen las STL (Standard Templates Libraries) dentro de la cual se
pueden encontrar plantillas para la manipulación de listas tales como: Vectores, Listas, Sets,
Maps, etc. Por otro lado, los usuarios de Borland C++ (Turbo C++ versión 1.01) pueden hacer uso
de la CLASSLIB, misma que posee las librerías para los propósitos mencionados.

Nota: En las siguientes secciones se presentarán seis programas, tres para simular listas basadas
en arreglos estáticos y tres para simular listas por medio de enlaces dinámicos (punteros). En
cuanto al material incluido se debe hacer las siguientes declaraciones:

Puesto que el material es puramente didáctico, cada programa se escribe en un mismo


archivo. La idea es no perder de vista el objetivo. Los entendidos sabrán que normalmente se
deben escribir archivos de cabecera, archivos de implementación y archivos de prueba por
separado.

Para cada una de las clases creadas en los programas se han elegido nombres en inglés. La
idea es que gran parte de la documentación e implementación referente a listas está en dicho
idioma, así, se le da al estudiante la idea básica de como operar con las librerías soportadas por
los compiladores Dev-Cpp, Borlan C++, y otros.
Igual, se debe observar que los métodos de las clases tienen nombres en inglés, y que con
el objetivo de establecer cierta estandarización todas las clases poseen los mismos métodos,
aunque cada una de ellas implementa los mismos a su manera.
Pilas o Stacks: Una PILA es una estructura en donde cada elemento es insertado y retirado del
tope de la misma, y debido a esto el comportamiento de una pila se conoce como LIFO (último
en entrar, primero en salir).
Un ejemplo de pila o stack se puede observar en el mismo procesador, es decir, cada vez
que en los programas aparece una llamada a una función el microprocesador guarda el estado de
ciertos registros en un segmento de memoria conocido como Stack Segment, mismos que serán
recuperados al regreso de la función.

Pila en arreglo estático: En el programa que se verá en seguida, se simula el comportamiento de


una estructura de pila. Aunque en el mismo se usa un arreglo estático de tamaño fijo se debe
mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras personas
se basan en listas dinámicas o enlazadas.

Para la implementación de la clase Stack se han elegido los métodos:


put(), poner un elemento en la pila
get(), retirar un elemento de la pila
empty(), regresa 1 (TRUE) si la pila esta vacia
size(), número de elementos en la pila
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

El atributo SP de la clase Stack es el puntero de lectura/escritura, es decir, el SP indica la


posición dentro de la pila en donde la función put() insertará el siguiente dato, y la posición
dentro de la pila de donde la función get() leerá el siguiente dato.

Cada vez que put() inserta un elemento el SP se decrementa.


Cada vez que get() retira un elemento el SP se incrementa.

En el siguiente ejemplo se analiza lo que sucede con el SP (puntero de pila) cuando se


guardan en la pila uno por uno los caracteres 'A', 'B', 'C' y 'D'. Observe que al principio el SP es
igual al tamaño de la pila.

Llenando la pila.
SP
|

| | | | | | al principio (lista vacía)

SP
|

push('A');
| | | | | A | después de haber agregado el primer elemento

...
SP
|

| | D | C | B | A | después de haber agregado cuatro elementos

Vaciando la pila.
SP
|

Pop();
| | D | C | B | A | después de haber retirado un elemento

...
SP
|

| | D | C | B | A | después de haber retirado todos los elementos

Nota: observe que al final la lista está vacía, y que dicho estado se debe a que el puntero está al final de la pila y no al
hecho de borrar físicamente cada elemento de la pila.
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

Ejemplo: Pila basada en un arreglo estático

#include <iostream>
using namespace std;

#define STACK_SIZE 256 /* capacidad máxima */


typedef char arreglo[STACK_SIZE];

class Stack {

int sp; /* puntero de lectura/escritura */


int items; /* número de elementos en lista */
int itemsize; /* tamaño del elemento */
arreglo pila; /* el arreglo */

public:
// constructor
Stack() {
sp = STACK_SIZE-1;
items = 0;
itemsize = 1;
}

// destructor
~Stack() {};

/* regresa el número de elementos en lista */


int size() { return items; }

/* regresa 1 si no hay elementos en la lista, o sea, si la lista está vacia */


int empty() { return items == 0; }

/* insertar elemento a la lista */


int put(char d)
{
if ( sp >= 0) {
pila[sp] = d;
sp --;
items ++;
}
return d;
}

/* retirar elemento de la lista */


Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

int get()
{
if ( ! empty() ) {
sp ++;
items --;
}
return pila[sp];
}

}; // fin de clase Stack

// Probando la pila.
// Nota: obseve cómo los elementos se ingresan en orden desde la A hasta la Z,
// y como los mismos se recuperán en orden inverso.
int main()
{
int d;
Stack s; // s es un objeto (instancia) de la clase Stack

// llenando la pila
for (d='A'; d<='Z'; d++) s.put(d);

cout << "Items =" << s.size() << endl;

// vaciando la pila
while ( s.size() ) cout << (char)s.get() << " ";

cout << "\nPara terminar oprima <Enter>...";


cin.get();
return 0;
}
}
Pila dinámica: En el siguiente programa se presenta una implementación de una
estructura dinámica tipo pila o stack. Es importante hacer notar que, a diferencia de una pila
basada en un arreglo estático, una pila enlazadada dinámicamente no posee de forma natural el
mecanismo de acceso por índices, en ese sentido, el programador puede crear los algoritmos
necesarios para permitir tal comportamiento. En la clase que presentaremos en el ejemplo no se
ha implementado el mecanismo de acceso por índices, ya que la misma se presenta como una
alternativa para la simulación de una pila o stack.

Uno de los puntos más destacables en cuando al uso de listas enlazadas dinámicamente es el
hecho de crear estructuras conocidas como nodos. Un nodo es una especie de eslabón (similar al
de una cadena de bicicleta), es decir, cada nodo se enlaza con otro a través de un puntero que
apunta a una estructura del mismo tipo que el nodo. Por ejemplo, para crear una estructura de
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

nodo para almacenar enteros y a la vez para apuntar a otro posible nodo podemos emplear la
sintaxis:
struct nodo {
int data;
nodo *siguiente;
};
Observe que con la declaración anterior estamos creando el tipo estructurado nodo,
mismo que posee a los miembros: data para guardar valores enteros, y siguiente para apuntar o
enlazar a un supuesto siguiente nodo.

Ya que las listas dinámicas inicialmente se encuentran vacías, y más aún, una lista dinámica no
posee una dirección establecida en tiempo de compilación ya que las dirección de memoria que
ocupará cada uno de los elementos se establecerá en tiempo de ejecución, entonces cómo
determinar la condición de vacío ?. En nuestro ejemplo usaremos un contador (ITEMS) que dicho
sea de paso, si ITEMS = 0, entonces la lista está vacía. (la condición de vacío también podría
determinarse al verificar el SP, es decir, si el SP = NULL, significa que la lista no posee elementos
).

Al hacer un análisis previo de los eventos que acontecerán en la pila y su puntero de lectura y
escritura (SP, que en esta ocasión es una estructura tipo nodo), se tiene lo siguiente:

1) Al principio la lista está vacia, en ese caso el SP es igual a NULL y, en consecuencia, el puntero
next también es NULL.
SP = NULL

| ???? | next |--> NULL

2) Después de agregar el primer elemento la situación se vería así:


SP = asignado
1

| data | next |--> NULL

3) Después de agregar otro elemento la situación se vería así:


SP = asignado
2 1

| data | next |--> | data | next |--> NULL


Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

Ejemplo: Pila basada en un arreglo dinámico

/*---------------------------------------------------------------+
+ Ejemplo de una pila (STACK) enlazada dinámicamente +
++
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
++
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ forma libre. +
+---------------------------------------------------------------*/

#include <iostream>
//#include <conio.h>

using namespace std;

/* tipo de dato que contendrá la lista */


typedef char DATA_TYPE;

// declaraci¢n de estructura nodo


struct nodo {
DATA_TYPE data;
nodo *next;
};

class StackDin {

// atributos
int ITEMS; /* número de elementos en la lista */
int ITEMSIZE; /* tamaño de cada elemento */
nodo *SP; /* puntero de lectura/escritura */

public:
// constructor
StackDin() : SP(NULL), ITEMS(0), ITEMSIZE(sizeof(DATA_TYPE)) {}

// destructor
~StackDin() {}

/* agregar componente a la lista */


DATA_TYPE put(DATA_TYPE valor)
{
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

nodo *temp;

temp = new nodo;


if (temp == NULL) return -1;

temp->data = valor;
temp->next = SP;
SP = temp;
ITEMS ++;
return valor;
}
int empty() { return ITEMS == 0; }

/* retirar elemento de la lista */


DATA_TYPE get()
{
nodo *temp;
DATA_TYPE d;

if ( empty() ) return -1;

d = SP->data;
temp = SP->next;
if (SP) delete SP;
SP = temp;
ITEMS --;
return d;
}

}; // fin de la clase StackDin

/* punto de prueba para la clase StackDin */


int main()
{
//clrscr();

StackDin s;
DATA_TYPE d;

for (d='A'; d<='Z'; d++) s.put(d);

while ( ! s.empty() )
cout << (DATA_TYPE)s.get() << " ";

cout << "\nPara terminar presione <Enter>...";


Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

cin.get();
return 0;
}
Colas o Queues
Una cola sencilla es una estructura en donde cada elemento es insertado Inmediatamente
después del último elemento insertado; y donde los elementos se retiran siempre por el frente
de la misma, debido a esto el comportamiento de un una cola se conoce como FIFO (primero en
entrar, primero en salir).

Un ejemplo a citar de cola es el comportamiento del buffer del teclado.

Cuando en el teclado se oprime una tecla, el código del carácter ingresado es trasladado y
depositado en un área de memoria intermedia conocida como "el buffer del teclado", para esto
el microprocesador llama a una rutina específica. Luego, para leer el carácter depositado en el
buffer existe otra función, es decir, hay una rutina para escribir y otra para leer los caracteres del
buffer cada una de las cuales posee un puntero; uno para saber en dónde dentro del buffer se
escribirá el siguiente código y otro para saber de dónde dentro del buffer se leerá el siguiente
código.

Cola en un arreglo estático En el programa que se ve en seguida, se simula el comportamiento de


una estructura de cola simple. Aunque en el mismo se usa un arreglo estático de tamaño fijo se
debe mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras
personas se basan en listas dinámicas o dinámicamente enlazadas.

Para la implementación de la clase Queue se han elegido los métodos:

put(), poner un elemento en la cola


get(), retirar un elemento de la cola
empty(), regresa 1 (TRUE) si la cola est vacía
size(), número de elementos en la cola
El atributo cabeza de la clase Queue es el puntero de lectura.
El atributo cola de la clase Queue es el puntero de escritura.
Es decir, la cola indica la posición dentro de la lista en donde la función put() insertará el
siguiente dato, y la cabeza indica la posición dentro de la lista de donde la función get() leerá el
siguiente dato.

Cada vez que put() inserta un elemento la cola se incrementa.


Cada vez que get() retira un elemento la cabeza se incrementa.
En el siguiente ejemplo se analiza lo que sucede con la cola y la cabeza (punteros de escritura y
de lectura de la Lista) cuando se guardan en la cola uno por uno los caracteres 'A', 'B', 'C' y 'D'.
Observe que al principio: cola = cabeza = cero.
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

Llenando la cola.
cola
|

| | | | | | al principio

|
cabeza
cola
|

put('A');
| A | | | | | después de haber agregado el primer elemento

|
cabeza
...
cola
|

| A | B | C | D | | después de haber agregado cuatro elementos

|
cabeza
Vaciando la cola.
cabeza
|

| A | B | C | D | | antes de haber retirado elementos

cabeza
|

get();
| A | B | C | D | | después de haber retirado un elemento
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

...

cabeza
|

al final
| A | B | C | D | | después de haber retirado todos los elementos

|
cola
Obsérvese que al final el cabeza apunta hacia el mismo elemento que la cola, es decir, la cola
vuelve a estar vacía. Puesto que la cola que estamos proyectando reside en un arreglo estático
los componentes del arreglo aún están dentro de la misma, salvo que para su recuperación se
debería escribir otro método. En una cola dinámica (como se demostrará más adelante) los
elementos retirados de la misma se eliminan de la memoria y podría no ser posible su
recuperación posterior.

Nota: En el programa que aparece en seguida, al tipo de lista implementado por la clase Queue
se le conoce como "lista circular" debido al comportamiento de sus punteros. Es decir si los
métodos para escribir o leer detectan que el puntero correspondiente ha sobrepasado el tamaño
máximo de elementos permitidos dentro de la cola, éste es puesto a cero.

Ejemplo: cola en un arreglo estático

/*---------------------------------------------------------------+
+ Ejemplo de una cola (QUEUE) basada en un arreglo estático +
++
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
++
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ Forma libre. +
+---------------------------------------------------------------*/
#include <iostream.h>

#define MAX_SIZE 256 /* capacidad máxima */


typedef char almacen[MAX_SIZE];

class Queue {

int cabeza; /* puntero de lectura */


int cola; /* puntero de escritura */
int ITEMS; /* número de elementos en la lista */
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

int ITEMSIZE; /* tamaño de cada elemento */


almacen alma; /* el almacen */

public:
// constructor
Queue() {
cabeza = 0;
cola = 0;
ITEMS = 0;
ITEMSIZE = 1;
}

// destructor
~Queue() {}

// regresa 1 (true) si la lista está vacia


int empty() { return ITEMS == 0; }

// insertar elemento a la lista


int put(int d)
{
if ( ITEMS == MAX_SIZE) return -1;
if ( cola >= MAX_SIZE) { cola = 0; }
alma[cola] = d;
cola ++;
ITEMS ++;
return d;
}

// Retirar elemento de la lista


int get()
{
char d;
if ( empty() ) return -1;
if ( cabeza >= MAX_SIZE ) { cabeza = 0; }
d = alma[cabeza];
cabeza ++;
ITEMS --;
return d;
}

// regresa el n£mero de elementos en lista


int size() { return ITEMS; }

}; // fin de la clase Queue


Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

// probando la cola
int main()
{
int d;
Queue q;

for (d='A'; d<='Z'; d++) q.put(d);

cout << "Items = " << q.size() << endl;

while ( q.size() ) {
cout << (char)q.get() << " ";
}

cout << "\nPara terminar oprima <Enter> ...";


cin .get();
return 0;
}
Ejemplo: cola en un arreglo dinámico

/*---------------------------------------------------------------+
+ Ejemplo de una cola (QUEUE) basada en un arreglo dinámico +
++
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
++
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ forma libre. +
+---------------------------------------------------------------*/
#include <iostream>

using namespace std;

typedef char DATA_TYPE;

struct nodo {
DATA_TYPE data;
nodo *next;
};

class QueueDin {
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

// atributos
int ITEMS, ITEMSIZE;
nodo *cola, *cabeza;

public:
// constructor
QueueDin() : cola(NULL), cabeza(NULL), ITEMS(0), ITEMSIZE(sizeof(DATA_TYPE)) {}

// destructor
~QueueDin() {}

/* agregar componente a la lista */


DATA_TYPE put(DATA_TYPE valor)
{
nodo *temp;

temp = new nodo;


if (temp == NULL) return -1;

ITEMS ++;
temp->data = valor;
temp->next = NULL;

if (cabeza == NULL)
{
cabeza = temp;
cola = temp;
} else
{
cola->next = temp;
cola = temp;
}
return valor;
}

// regresa 1 (true) si la lista está vacia


int empty() { return ITEMS == 0; }

/* retirar elemento de la lista */


DATA_TYPE get()
{
nodo *temp;
DATA_TYPE d;
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

if ( empty() ) return -1;

d = cabeza->data;
temp = cabeza->next;
if (cabeza) delete cabeza;
cabeza = temp;
ITEMS --;
return d;
}

}; // fin de la clase QueueDin

/* punto de prueba */
int main()
{
QueueDin s;
DATA_TYPE d;

// llenando la cola
for (d='A'; d<='Z'; d++) {
s.put(d);
cout << d << " ";
}

cout << endl;


// vaciando la cola
while ( ! s.empty() )
cout << (DATA_TYPE)s.get() << " ";

cout << "\nPara terminar presione <Enter>...";


cin.get();
return 0;
}

Colas de doble enlace


Una cola doble es una estructuras en donde cada elemento puede ser insertado y recuperado
por la parte del frente (cabeza) o por la parte de atrás (cola) de la lista. A diferencia de una cola
sencilla, en donde solo se necesitan un método para leer y otro para escribir componentes en la
lista, en una doble cola debe haber dos métodos para leer ( uno para leer por el frente y uno para
leer por atrás) y dos métodos para escribir ( uno para escribir por el frente y uno para escribir por
atráshttps://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II).

En el programa que se verá en seguida, se simula el comportamiento de una estructura de cola


doble con base en un arreglo estático. En dicho programa se declara e implementa la clase
SDQueue con los siguientes métodos:
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

put_front(), poner un elemento en el frente de la cola


put_back(), poner un elemento en la parte tracera de la cola
get_front(), retirar un elemento de la parte frontal de la cola
get_back(), retirar un elemento de la parte tracera de la cola
empty(), regresa 1 (TRUE) si la cola est vacia
size(), número de elementos en la cola
Nota: observe que para los métodos put_front() y get_front() se hace uso de la función
memmove(), esto es necesario debido al hecho de que put_front() tiene que mover una posición
hacia atras todos los elementos en la lista antes de insertar el componente indicado; por otro
lado, la función get_front() tiene que mover una posición hacia adelante a todos los elementos
que le siguen al primer elemento.

Ejemplo: doble cola en un arreglo estático

/*------------------------------------------------------------------+
+ Ejemplo de una cola doble (DQUEUE) basada en un arreglo est tico +
++
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
++
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ Forma libre. +
+------------------------------------------------------------------*/

#include <iostream.h>
#include <mem.h> // por memmove

// using namespace std;


#define MAX_SIZE 256
#define t_error -1;

typedef int DATA_TYPE; // máximo número de elementos


typedef int almacen[MAX_SIZE];

class SDQueue {
// atributos
int itemsize; // tamaño de cada elemento
int items; // número de elementos
int cola, cabeza; // punteros de lectura y escritura
almacen alma; // el almacen o arreglo

public:
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

// constructor
SDQueue() : cola(0), cabeza(0), items(0), itemsize(sizeof(DATA_TYPE)) {}

// destructor
~SDQueue() {}

int empty() { return items == 0; }

int size() { return items; }

/* agregar componente en la parte tracera de la lista */


DATA_TYPE put_back(DATA_TYPE valor)
{
if (items == MAX_SIZE) return t_error;
alma[cola] = valor;
items ++;
cola ++;
return valor;
}

/* agregar componente en la parte delantera de la lista */


DATA_TYPE put_front(DATA_TYPE valor)
{
if (items == MAX_SIZE) return t_error;
memmove((void *)&alma[cabeza+1], (void*)&alma[cabeza], items*itemsize);
alma[cabeza] = valor;
items ++;
cola ++;
return valor;
}

/* retirar elemento de la parte frontal de la lista */


DATA_TYPE get_front()
{
DATA_TYPE d;

if ( empty() ) return t_error;


items --;
cola --;
d = alma[cabeza];
memmove((void*)&alma[cabeza], (void*)&alma[cabeza+1], items*itemsize);
return d;
}
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

/* retirar elemento de la parte tracera de la lista */


DATA_TYPE get_back()
{
DATA_TYPE d;

if ( empty() ) return t_error;


items--;
cola --;
d = alma[cola];
return d;
}

}; // fin de la clase SDQueue

/* punto de prueba */
int main()
{
SDQueue s;
DATA_TYPE d;

for (d='A'; d<='Z'; d++) s.put_back(d);

while ( ! s.empty() )
cout << (char)s.get_front() << " ";

cout << "\nPara terminar presione <Enter>...";


cin.get();
return 0;
}
Una cola doblemente encadenada es una estructuras en donde cada elemento puede ser
insertado y recuperado por la parte del frente (cabeza) o por la parte de atras (cola) de la lista. A
diferencia de una cola sencilla, en donde solo se necesita un puntero a un siguiente elemento, la
estructura del nodo para una doble cola debe poseer un puntero a un posible siguiente elemento
y un puntero a otro posible anterior elemento. Por ejemplo, para crear una estructura de nodo
con doble enlace para coleccionar números enteros podemos usar la sintaxis:

struct nodo {
int data;
nodo *next, *prev;
};
Gráficamente podemos imaginar la estructura anterior como:

<--| prev | data | next |-->


Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

En el programa que se verá en seguida, se simula el comportamiento de una estructura de cola


de doble enlace. Para la implementación de la clase DDqueue en el programa se han elegido los
métodos:

put_front(), poner un elemento en el frente de la cola


put_back(), poner un elemento en la parte tracera de la cola
get_front(), retirar un elemento de la parte frontal de la cola
get_back(), retirar un elemento de la parte tracera de la cola
empty(), regresa 1 (TRUE) si la cola est vacia
size(), n£mero de elementos en la cola
/*---------------------------------------------------------------+
+ ejemplo de una cola doblemente enlazada (Dqueue) basada en un +
+ arreglo dinámico +
++
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
++
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ forma libre. +
+---------------------------------------------------------------*/

#include <iostream.h>
#include <conio.h>

// using namespace std;

typedef char DATA_TYPE;

struct nodo {
DATA_TYPE data;
nodo *next, *prev;
};

class DDqueue {

int itemsize, items;


nodo *cola, *cabeza;

public:
// constructor
DDqueue() : cola(NULL), cabeza(NULL), items(0), itemsize(sizeof(DATA_TYPE)) {}
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

// destructor
~DDqueue() {}

/* agregar componente en la parte tracera de la lista */


DATA_TYPE put_back(DATA_TYPE valor)
{
nodo *temp;

temp = new nodo;


if (temp == NULL) return -1;

temp->data = valor;

items ++;
if (cabeza == NULL )
{
temp->next = NULL;
temp->prev = NULL;
cabeza = temp;
cola = temp;
} else
{
cola->next = temp;
temp->prev = cola;
cola = temp;
cola->next = NULL;
}
return valor;
}

/* agregar componente en la parte frontal de la lista */


DATA_TYPE put_front(DATA_TYPE valor)
{
nodo *temp;

temp = new nodo;


if (temp == NULL) return -1;

temp->data = valor;

items ++;
if (cabeza == NULL )
{
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

temp->next = NULL;
temp->prev = NULL;
cabeza = temp;
cola = temp;
} else
{
cabeza->prev = temp;
temp->next = cabeza;
cabeza = temp;
cabeza->prev = NULL;
}
return valor;
}

// regresa true si la lista está vacia


int empty() { return items == 0; }

/* retirar elemento de la parte frontal lista */


DATA_TYPE get_front()
{
nodo *temp;
DATA_TYPE d;

if ( empty() ) return -1;

items --;
d = cabeza->data;
temp = cabeza->next;
if (cabeza) delete cabeza;
cabeza = temp;
return d;
}

/* retirar elemento de la parte tracera de la lista */


DATA_TYPE get_back()
{
nodo *temp;
DATA_TYPE d;

if ( empty() ) return -1;

items--;
d = cola->data;
temp = cola->prev;
Universidad Mariano Gálvez
Facultad de Ingeniería en Sistemas de Información
Cat. Ing. Ilonkka Carolina Cabrera Cintora
Curso: Programación I
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Estructuras_II

if (cola) delete cola;


cola = temp;
return d;
}

}; // fin de la clase DDqueue

/* punto de prueba */
int main()
{
clrscr();

DDqueue s;
DATA_TYPE d;

// insertando elementos en la parte tracera


for (d='A'; d<='Z'; d++) s.put_back(d);

// insertando en la parte delantera


for (d=9; d>=0; d--)s.put_front(d+'0');

// vaciando la lista
while ( ! s.empty() )
cout << (DATA_TYPE)s.get_front() << " ";

cout << "\nPara terminar presione <Enter>...";


cin.get();
return 0;
}

También podría gustarte