Académique Documents
Professionnel Documents
Culture Documents
Programacin en C++/Estructuras II
Editores:
Oscar E. Palacios [1]
Punteros Plantillas
Introduccin
Muchos autores comienzan por definir los conceptos de estructura de datos a raiz de estructuras conocidas como
listas. En el mismo contexto, suele suceder que a dichas listas tambin se les conoce como secuencias y/o
colecciones de datos. Hay que decir que dichos autores estn (en parte) en lo correcto, ya que una lista (de cualquier
tipo) es una estructura ideada con el propsito de albergar datos agrupados bajo un mismo nombre. Al respecto,
podemos pensar que las listas son como arreglos de datos, es decir, para hacer una introduccin al manejo y
programacin de listas encadenadas podemos tomar como punto de partida a los arreglos estticos. Es as como en
esta secccin se descubrir la forma de operacin de tres tipos comnes de listas conocidas como: PILAS, COLAS
Y DOBLE COLA (STACK, QUEUE, DQUEUE). En programacin, el uso de listas es una prctica 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++ [2] ) pueden aprovechar las ventajas que ofrecen las STL (Standard Templates
Libraries) dentro de la cual se pueden encontrar plantillas para la manipulacin de listas tales como: Vectores, Listas,
Sets, Maps, etc. Por otro lado, los usuarios de Borland C++ ( Turbo C++ version 1.01 [3] ) pueden hacer uso de la
CLASSLIB, misma que posee las librerias para los propsitos mencionados.
Nota: En las siguientes secciones se presentarn seis programas, tres para simular listas basadas en arreglos estticos
y tres para simular listas por medio de enlaces dinmicos (punteros). En cuanto al material incluido se debe hacer las
siguientes declaraciones:
1. Puesto que el material es puramente didctico, cada programa se escribe en un mismo archivo. La idea es no
perder de vista el objetivo. Los entendidos sabrn que normalmente se deben escribir archivos de cabecera,
archivos de implementacion y archivos de prueba por separado.
2. Para cada una de las clases creadas en los programas se han elegido nombres en ingles. La idea es que gran parte
de la documentacin e implementacin referente a listas est en dicho idioma, as, se le da al estudiante la idea
bsica de como operar con las libreras soportadas por los compiladores Dev-Cpp, Borlan C++, y otros.
3. Igual, se debe observar que los mtodos de las clases tienen nombres en ingles, y que con el objetivo de
establecer cierta estandarizacin todas las clases poseen los mismos mtodos, aunque cada una de ellas
implementa los mismos a su manera.
Pilas o Stacks
Una PILA es una estructuras en donde cada elemento es insertado y retirado
del tope de la misma, y debido a esto el comportamiento de un 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 funcin el microprocesador guarda el estado de ciertos registros en un segmento de
memoria conocido como Stack Segment, mismos que sern recuperados al regreso de la funcin.
Programacin en C++/Estructuras II
push('A');
despus de haber agregado el primer elemento
...
SP
|
+---+---+---+---+---+
|
| D | C | B | A |
+---+---+---+---+---+
Vaciando la pila.
SP
|
+---+---+---+---+---+
|
| D | C | B | A |
+---+---+---+---+---+
...
pop();
despus de haber retirado un elemento
Programacin en C++/Estructuras II
SP
|
+---+---+---+---+---+
|
| D | C | B | A |
+---+---+---+---+---+
Nota: observe que al final la lista est vacia, y que dicho estado se debe a que
el puntero
de la pila.
Programacin en C++/Estructuras II
items ++;
}
return d;
}
/* retirar elemento de la lista */
int get()
{
if ( ! empty() ) {
sp ++;
items --;
}
return pila[sp];
}
}; // fin de clase Stack
// probando la pila.
// Nota: obseve cmo los elementos se ingresan en orden desde la A
hasta la Z,
// y como los mismos se recupern 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 dinmica
En el siguiente programa se presenta una implementacin de una estructura dinmica tipo pila o stack. Es importante
hacer notar que, a diferencia de una pila basada en un arreglo esttico, una pila enlazadada dinmicamente 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
Programacin en C++/Estructuras II
mecanismo de acceso por ndices, ya que la misma se presenta como una alternativa para la simulacin de una pila o
stack.
Uno de los puntos ms destacables en cuando al uso de listas enlazadas dinmicamente es el hecho de crear
estructuras conocidas como nodos. Un nodo es una especie de eslabn ( similar al de una cadena de bicicleta ), es
decir, cada nodo se enlaza con otro a travs de un puntero que apunta a una estructura del mismo tipo que el nodo.
Por ejemplo, para crear una estructura de 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 declaracin 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 dinmicas inicialmente se encuentran vacias, y ms an, una lista dinmica no posee una direccin
establecida en tiempo de compilacin ya que las direccin de memoria que ocupar cada uno de los elementos se
establecer en tiempo de ejecucin, entonces cmo determinar la condicin de vacio ?. En nuestro ejemplo usaremos
un contador ( ITEMS ) que dicho sea de paso, si ITEMS = 0, entonces la lista est vacia. ( la condicin de vacio
tambin podra determinarse al verificar el SP, es decir, si el SP = NULL, significa que la lista no posee elementos ).
Al hacer un anlisis previo de los eventos que acontecern en la pila y su puntero de lectura y escritura (SP, que en
esta ocasin 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
tambin es NULL.
SP = NULL
+------+------+
| ???? | next |--> NULL
+------+------+
2) Despus de agregar el primer elemento la situacin se vera as:
SP = asignado
1
+------+------+
| data | next |--> NULL
+------+------+
3) Despus de agregar otro elemento la situacin se vera as:
SP = asignado
2
1
+------+------+
+------+------+
| data | next |--> | data | next |--> NULL
+------+------+
+------+------+
Ejemplo: Pila basada en un arreglo dinmico
/*---------------------------------------------------------------+
+ ejemplo de una pila ( STACK ) enlazada dinmicamente +
Programacin en C++/Estructuras II
+ +
+ 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;
// declaracin de estructura nodo
struct nodo {
DATA_TYPE data;
nodo *next;
};
class StackDin {
// atributos
int ITEMS;
/* nmero de elementos en la lista */
int ITEMSIZE; /* tamao 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)
{
nodo *temp;
temp = new nodo;
if (temp == NULL) return -1;
temp->data = valor;
temp->next = SP;
SP = temp;
Programacin en C++/Estructuras II
ITEMS ++;
return valor;
}
int empty() { return ITEMS == 0; }
Programacin en C++/Estructuras II
Colas o Queues
Una cola sencilla es una estructura en donde cada elemento es insertado
inmediatamente despus 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 cdigo del carcter ingresado es trasladado y depositado en una rea de
memoria intermedia conocida como "el buffer del teclado", para esto el microprocedador llama a una rutina
especfica. Luego, para leer el carcter depositado en el buffer existe otra funcin, 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 donde
dentro del buffer se escribir el siguiente cdigo y otro para saber de donde dentro del buffer se leer el siguiente
cdigo.
vacia
al principio
put('A');
Programacin en C++/Estructuras II
| A |
|
|
|
|
+---+---+---+---+---+
|
cabeza
9
despus de haber agregado el primer elemento
...
cola
|
+---+---+---+---+---+
| A | B | C | D |
|
+---+---+---+---+---+
|
cabeza
Vaciando la cola.
cabeza
|
+---+---+---+---+---+
| A | B | C | D |
|
+---+---+---+---+---+
cabeza
|
+---+---+---+---+---+
| A | B | C | D |
|
+---+---+---+---+---+
get();
despus de haber retirado un elemento
...
cabeza
|
+---+---+---+---+---+
| A | B | C | D |
|
+---+---+---+---+---+
|
cola
al final
despus de haber retirado todos los elementos
Observese que al final el cabeza apunta hacia el mismo elemento que la cola, es decir, la cola vuelve a estar vacia.
Puesto que la cola que estamos proyectando reside en un arreglo esttico los componentes del arreglo an estn
dentro de la misma, salvo que para su recuperacin se debera escribir otro mtodo. En una cola dinmica (como se
demostrar ms adelante) los elementos retirados de la misma se eliminan de la memoria y podra no ser posible su
recuperacin 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 mtodos para escribir o leer detectan que el
puntero correspondiente ha sobrepasado el tamao mximo de elementos permitidos dentro de la cola, ste es puesto
a cero.
Ejemplo: cola en un arreglo esttico
Programacin en C++/Estructuras II
/*---------------------------------------------------------------+
+ ejemplo de una cola (QUEUE) basada en un arreglo esttico +
+ +
+ 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 mxima */
typedef char almacen[MAX_SIZE];
class Queue {
int cabeza; /* puntero de lectura */
int cola; /* puntero de escritura */
int ITEMS; /* nmero de elementos en la lista */
int ITEMSIZE; /* tamao 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;
10
Programacin en C++/Estructuras II
}
// 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 nmero de elementos en lista
int size() { return ITEMS; }
}; // fin de la clase Queue
// 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 dinmico
/*---------------------------------------------------------------+
+ ejemplo de una cola (QUEUE) basada en un arreglo dinmico +
+ +
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
+ +
+ Manifiesto: +
11
Programacin en C++/Estructuras II
+ 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 {
// 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;
12
Programacin en C++/Estructuras II
cola = temp;
}
return valor;
}
// regresa 1 (true) si la lista est vacia
int empty() { return ITEMS == 0; }
13
Programacin en C++/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 esttico. En dicho programa se declara e implementa la clase SDQueue con los siguientes mtodos:
put_front(),
put_back(),
get_front(),
get_back(),
empty(),
size(),
Nota: observe que para los mtodos put_front() y get_front() se hace uso de la funcin memmove(), esto es necesario
debido al hecho de que put_front() tiene que mover una posicin hacia atras todos los elementos en la lista antes de
insertar el componente indicado; por otro lado, la funcin get_front() tiene que mover una posicin hacia adelante a
todos los elementos que le siguen al primer elemento.
Ejemplo: doble cola en un arreglo esttico
/*------------------------------------------------------------------+
+ 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; // mximo nmero de elementos
typedef int almacen[MAX_SIZE];
class SDQueue {
// atributos
int itemsize; // tamao de cada elemento
14
Programacin en C++/Estructuras II
int items;
// nmero de elementos
int cola, cabeza; // punteros de lectura y escritura
almacen alma; // el almacen o arreglo
public:
// 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;
}
15
Programacin en C++/Estructuras II
d = alma[cabeza];
memmove((void*)&alma[cabeza], (void*)&alma[cabeza+1],
items*itemsize);
return d;
}
/* 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 nmeros enteros podemos usar la sintaxis:
struct nodo {
int data;
nodo *next, *prev;
};
Grficamente podemos imaginar la estructura anterior como:
16
Programacin en C++/Estructuras II
+------+------+------+
<--| prev | data | next |-->
+------+------+------+
En el programa que se ver en seguida, se simula el comportamiento de una estructura de cola de doble enlace. Para
la implementacin de la clase DDqueue en el programa se han elegido los mtodos:
put_front(),
put_back(),
get_front(),
get_back(),
empty(),
size(),
/*---------------------------------------------------------------+
+ ejemplo de una cola doblemente enlazada (Dqueue) basada en un +
+ arreglo dinmico +
+ +
+ 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)) {}
17
Programacin en C++/Estructuras II
// destructor
~DDqueue() {}
18
Programacin en C++/Estructuras II
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; }
19
Programacin en C++/Estructuras II
20
Referencias
[1] mailto:oscarpalacios1@yahoo. com. mx
[2] http:/ / www. bloodshed. net/ devcpp. html
[3] http:/ / dn. codegear. com/ article/ 21751
Licencia
Creative Commons Attribution-Share Alike 3.0
//creativecommons.org/licenses/by-sa/3.0/
21