Вы находитесь на странице: 1из 14

Pilas o Stocks

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.

Pila en arreglo esttico


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 esttico de tamao fijo se debe mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras personas se basan en listas dinmicas o enlazadas. Para la implementacin de la clase Stack se han elegido los mtodos:
Put (), poner un elemento en la pila Get (), retirar un elemento de la pila Empty (), regresa 1 (TRUE) si la pila esta vacia Size (), nmero de elementos en la pila El atributo SP de la clase Stack es el puntero de lectura/escritura, es decir, el SP Indica la posicin dentro de la pila en donde la funcin put () insertar el siguiente Dato, y la posicin dentro de la pila de donde la funcin 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 tamao de la pila.

Llenando la pila.
SP | +---+---+---+---+---+ | | | | | | +---+---+---+---+---+ SP |

Al principio (lista vacia)

+---+---+---+---+---+ | | | | | A | +---+---+---+---+---+

push ('A'); despus de haber agregado el primer elemento

...
SP | +---+---+---+---+---+ | | D | C | B | A | +---+---+---+---+---+

despus de haber agregado cuatro elementos

Vaciando la pila.
SP | +---+---+---+---+---+ | | D | C | B | A | +---+---+---+---+---+

pop (); despus de haber retirado un elemento

...
SP | +---+---+---+---+---+ | | D | C | B | A | despus de haber retirado todos los elementos +---+---+---+---+---+ Nota: observe que al final la lista est vacia, y que dicho estado se debe a que el puntero est al final de la pila y no al hecho de borrar fsicamente cada elemento de la pila.

Ejemplo: Pila basada en un arreglo esttico


#include <iostream> Using namespace STD; #define STACK_SIZE 256 /* capacidad mxima */ Typedef char arreglo [STACK_SIZE]; Class Stack { int int Int Arreglo public: // constructor Stack () { Sp = STACK_SIZE-1; sp; /* puntero de lectura/escritura */ items; /* nmero de elementos en lista */ itemsize; /* tamao del elemento */ pila; /* el arreglo */

Items = 0; Itemsize = 1; } // Destructor ~Stack() {}; /* Regresa el nmero 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 ;} /* inserter element a la lista */ Int put (char d) { If (sp >= 0) { Pila [sp] = d; Sp --; 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 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 eslavon ( 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 + + + + 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; 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>..."; cin.get(); return 0; }

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 caracter ingresado es trasladado y depositado en una ara de memoria intermedia conocida como "el buffer del teclado", para esto el microprocedador llama a una rutina especfica. Luego, para leer el caracter depositado en el buffer existe otra funcin, es decir, hay una rutina para excribir 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.

Cola en un arreglo esttico


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 esttico de tamaoo fijo se debe mencionar que normalmente las implementaciones hechas por fabricantes y/o terceras personas se basan en listas dinmicas o dinamicamente enlazadas. Para la implementacin de la clase Queue se han elegido los mtodos:
put(), poner un elemento en la cola get(), retirar un elemento de la cola empty(), regresa 1 (TRUE) si la cola est vacia size(), nmero 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 posicin dentro de la lista en donde la funcin put() insertar el siguiente dato, y la cabeza indica la posicin dentro de la lista de donde la funcin 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 siguente 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.

Llenando la cola.
cola | +---+---+---+---+---+

| | | | | | +---+---+---+---+---+ | cabeza cola | +---+---+---+---+---+ | A | | | | | +---+---+---+---+---+ | cabeza

al principio

put('A'); despus de haber agregado el primer elemento

...
cola | +---+---+---+---+---+ | A | B | C | D | | +---+---+---+---+---+ | cabeza

despus de haber agregado cuatro elementos

Vaciando la cola.
cabeza | +---+---+---+---+---+ | A | B | C | D | | +---+---+---+---+---+ cabeza | +---+---+---+---+---+ | A | B | C | D | | +---+---+---+---+---+

antes de haber retirado elementos

get(); despus de haber retirado un elemento

...
cabeza | +---+---+---+---+---+ al final | A | B | C | D | | despus de haber retirado todos los elementos +---+---+---+---+---+ | cola

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


/*---------------------------------------------------------------+ + 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; int cola; int ITEMS; int ITEMSIZE; almacen alma; /* /* /* /* /* puntero de lectura */ puntero de escritura */ nmero de elementos en la lista */ tamao de cada elemento */ 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 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: + + 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; 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; 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; }

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 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; } /* 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; } /* 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; }