Professional Documents
Culture Documents
Una pila (stack en ingls) es una lista ordinal o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del ingls Last In First Out, ltimo en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el rea de informtica debido a su simplicidad y ordenacin implcita de la propia estructura.
Para el manejo de los datos se cuenta con dos operaciones bsicas:apilar (push), que coloca un objeto en la pila, y su operacin inversa, retirar (o desapilar, pop), que retira el ltimo elemento apilado. En cada momento slo se tiene acceso a la parte superior de la pila, es decir, al ltimo objeto apilado (denominado TOS, Top of Stack en ingls). La operacin retirar permite la obtencin de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS. Por analoga con objetos cotidianos, una operacin apilar equivaldra a colocar un plato sobre una pila de platos, y una operacin retirar a retirarlo. Las pilas suelen emplearse en los siguientes contextos:
y y y
Evaluacin de expresiones en notacin postfija (notacin polaca inversa). Reconocedores sintcticos de lenguajes independientes del contexto Implementacin de recursividad.
Historia
El mtodo de pila para la evaluacin de expresiones fue propuesto en 1955 y dos aos despus patentado por Fiedrich L.Bauer, quin recibi en 1988 el premio "IEEE Computer Society Pioneer Award" por su trabajo en el desarrollo de dicha estructura de datos.
Una pila cuenta con 2 operaciones imprescindibles: apilar y desapilar, a las que en las implementaciones modernas de las pilas se suelen aadir ms de uso habitual.
y y y y y
[editar] Implementacin
Un requisito tpico de almacenamiento de una pila de n elementos es O(n). El requisito tpico de tiempo de O(1) las operaciones tambin son fciles de satisfacer con un array o con listas enlazadas simples. La biblioteca de plantillas de C++ estndar proporciona una "pila" clase templated que se limita a slo apilar/desapilar operaciones. Java contiene una biblioteca de la clase Pila que es una especializacin de Vector. Esto podra ser considerado como un defecto, porque el diseo heredado get () de Vector mtodo LIFO ignora la limitacin de la Pila.
Crear: se crea la pila vaca. Apilar: se aade un elemento a la pila.(push) Desapilar: se elimina el elemento frontal de la pila.(pop) Cima: devuelve el elemento que esta en la cima de la pila. (top o peek) Vaca: devuelve cierto si la pila est vaca o falso en caso contrario.
Estos son ejemplos sencillos de una pila con las operaciones descritas anteriormente (pero no hay comprobacin de errores).
[editar] EN PYTHON
class Stack(object): def __init__(self): self.stack_pointer = None def push(self, element): self.stack_pointer = Node(element, self.stack_pointer ) def pop(self): e = self.stack_pointer .element self.stack_pointer = self.stack_pointer .next return e def peek(self): return self.stack_pointer .element def __len__(self): i = 0 sp = self.stack_pointer while sp: i += 1 sp = sp.next return i class Node(object): def __init__(self, element=None, next=None): self.element = element self.next = next if __name__ == '__main__' : # small use example s = Stack() [s.push(i) for i in xrange(10)] print [s.pop() for i in xrange(len(s))]
[editar] EN MAUDE
La PilaNV es la pila no vaca, que diferenciamos de la pila normal a la hora de tomar en cuenta errores. El elemento X representa el tipo de valor que puede contener la pila: entero, carcter, registro....
fmod PILA -GENERICA {X :: TRIV} is sorts Pila{X} PilaNV{X}. subsorts PilaNV{X} < Pila{X}. ***generadores: op crear: -> Pila {X} [ctor]. op apilar : X$Elt Pila{X} -> PilaNV{X} [ctor]. ***constructores op desapilar : Pila{X} -> Pila{X}.
***selectores op cima : PilaNV{X} -> X$Elt. ***variables var P : Pila{X}. var E : X$Elt. ***ecuaciones eq desapilar (crear) = crear. eq desapilar(apilar(E, P)) = P. eq cima(apilar(E, P)) = E. endfm
typedef struct { int tope; int item[TAM]; }pila; int full(pila *); int empty(pila *); void push(pila *, int); void pop(pila *,int *); void main() { pila p,t; int dato,opc,elemento,flag =0; p.tope=0; do { clrscr(); printf("\nMENU-PILA"); printf("\n1-> Insertar elemento" ); printf("\n2-> Eliminar elemento" ); printf("\n3-> Eliminar elemento X" ); printf("\n4-> Visualizar" ); printf("\n5-> Salir"); printf("\n\nDe su opcin : " ); scanf("%d",&opc); switch(opc) { case 1: if(!full(&p)) // si pila no esta llena { printf("\nDe el elemento a insertar: " ); scanf("%d",&dato); push(&p,dato); printf("\nElemento insertado..." ); } else { printf("\nERROR: Pila llena" ); } break; case 2: if(!empty(&p)) { pop(&p,&dato); printf("\nEl elemento eliminado es %d" ,dato); } else { printf("\nERROR: Pila vaca" ); } break; case 3: if(!empty(&p)) {
printf("eliminar elemento seleccionado: " ); scanf("%d",&elemento); if(p.tope != 1){ t.tope=0; do { pop(&p,&dato); if (dato != elemento) { push(&t,dato); } }while(!empty(&p)); do { pop(&t,&dato); push(&p,dato); }while(!empty(&t)); } else if(dato == elemento){pop(&p,&dato);} else {printf("el elemento no se encuentra en la pila");} } else { printf("\nERROR: Pila vaca" ); } break; case 4: if(!empty(&p)) { t.tope=0; do { pop(&p,&dato); printf("\n%d",dato); push(&t,dato); }while(!empty(&p)); do { pop(&t,&dato); push(&p,dato); }while(!empty(&t)); } else { printf("\nERROR: Pila vac a"); } break; case 5: flag=1; break; case 6: flag=0; break; default: printf("\nOpcin no v lida..." );
} if(!flag) { printf("\n\nPresione una tecla para continuar..." ); getch(); } }while(!flag); } int full(pila *p) { return(p->tope==MAX); } int empty(pila *p) { return(p->tope==0); } void push(pila *p,int dato) { if(!full(p)) { (p->tope)++; p->item[p->tope]=dato; } else printf("\nOVERFLOW" ); } void pop(pila *p,int *dato) { if(!empty(p)) { *dato=p->item[p->tope]; (p->tope)--; } else printf("\nUNDERFLOW" ); }
//elemento[1]=dato
El tipo base de la estructura FIFO (el primero en entrar es el primero en salir)es la cola, y la combinacin de las operaciones de la pila y la cola es proporcionado por el deque. Por ejemplo, el cambio de una pila en una cola en un algoritmo de bsqueda puede cambiar el algoritmo de bsqueda en primera profundidad (en ingls, DFS) por una bsqueda en amplitud (en ingls, BFS). Una pila acotada es una pila limitada a un tamao mximo impuesto en su especificacin.
Una operacin apilar, en el que un elemento de datos se coloca en el lugar apuntado por el puntero de pila, y la direccin en el puntero de pila se ajusta por el tamao de los datos de partida. Una operacin desapilar: un elemento de datos en la ubicacin actual apuntado por el puntero de pila es eliminado, y el puntero de pila se ajusta por el tamao de los datos de partida.
Hay muchas variaciones en el principio bsico de las operaciones de pila. Cada pila tiene un lugar fijo en la memoria en la que comienza. Como los datos se aadirn a la pila, el puntero de pila es desplazado para indicar el estado actual de la pila, que se expande lejos del origen (ya sea hacia arriba o hacia abajo, dependiendo de la aplicacin concreta). Por ejemplo, una pila puede comenzar en una posicin de la memoria de mil, y ampliar por debajo de las direcciones, en cuyo caso, los nuevos datos se almacenan en lugares que van por debajo de 1000, y el puntero de pila se decrementa cada vez que un nuevo elemento se agrega. Cuando un tema es eliminado de la pila, el puntero de pila se incrementa. Los punteros de pila pueden apuntar al origen de una pila o de un nmero limitado de direcciones, ya sea por encima o por debajo del origen (dependiendo de la direccin en que crece la pila), sin embargo el puntero de pila no puede cruzar el origen de la pila. En otras palabras, si el origen de la pila est en la direccin 1000 y la pila crece hacia abajo (hacia las direcciones 999, 998, y as sucesivamente), el puntero de pila nunca debe ser incrementado ms all de 1000 (para 1001, 1002, etc.) Si un desapilar operacin en la pila hace que el puntero de pila se deje atrs el origen de la pila, una pila se produce desbordamiento. Si una operacin de apilar hace que el puntero de pila incremente o decremente ms all del mximo de la pila, en una pila se produce desbordamiento. La pila es visualizada ya sea creciente de abajo hacia arriba (como pilas del mundo real), o, con el mximo elemento de la pila en una posicin fija, o creciente, de izquierda a derecha, por lo que el mximo elemento se convierte en el mximo a "la derecha". Esta visualizacin puede ser independiente de la estructura real de la pila en la memoria. Esto significa que rotar a la derecha es mover el primer elemento a la tercera posicin, la segunda a la primera y la tercera a la segunda. Aqu hay dos equivalentes visualizaciones de este proceso:
Manzana
Pltano
Pltano Fresa
==rotar a la derecha==>
Fresa Manzana
Una pila es normalmente representada en los ordenadores por un bloque de celdas de memoria, con los "de abajo" en una ubicacin fija, y el puntero de pila de la direccin actual de la "cima" de clulas de la pila. En la parte superior e inferior se utiliza la terminologa con independencia de que la pila crece realmente a la baja de direcciones de memoria o direcciones de memoria hacia mayores. Apilando un elemento en la pila,se ajusta el puntero de pila por el tamao de elementos (ya sea decrementar o incrementar, en funcin de la direccin en que crece la pila en la memoria), que apunta a la prxima celda, y copia el nuevo elemento de la cima en rea de la pila. Dependiendo de nuevo sobre la aplicacin exacta, al final de una operacin de apilar, el puntero de pila puede sealar a la siguiente ubicacin no utilizado en la pila, o tal vez apunte al mximo elemento de la pila. Si la pila apunta al mximo elemento de la pila, el puntero de pila se actualizar antes de que un nuevo elemento se apile, si el puntero que apunta a la prxima ubicacin disponible en la pila, que se actualizar despus de que el mximo elemento se apile en la pila. Desapilando es simplemente la inversa de apilar. El primer elemento de la pila es eliminado y el puntero de pila se actualiza, en el orden opuesto de la utilizada en la operacin de apilar.
Muchas pilas basadas en los microprocesadores se utilizan para aplicar el lenguaje de programacin Forth en el nivel de microcdigo. Pila tambin se utilizaron como base de una serie de mainframes y miniordenadores. Esas mquinas fueron llamados pila de mquinas, el ms famoso es el Burroughs B 000
Apilar cuando se enfrentan a un operando y Desafilar dos operandos y evaluar el valor cuando se enfrentan a una operacin. Apilar el resultado.
De la siguiente manera (la Pila se muestra despus de que la operacin se haya llevado a cabo):
ENTRADA 1 2 + 4 * 3 + OPERACION Apilar operando Apilar operando Aadir Apilar operando Multiplicar Apilar operando Aadir PILA 1 1, 2 3 3, 4 12 12, 3 15
El resultado final, 15, se encuentra en la parte superior de la pila al final del clculo.
Artculo principal: Pila basada en la asignacin de memoria y Pila mquina. Una serie de lenguajes de programacin estn orientadas a la pila, lo que significa que la mayora definen operaciones bsicas (aadir dos nmeros, la impresin de un carcter) cogiendo sus argumentos de la pila, y realizando de nuevo los valores de retorno en la pila. Por ejemplo, PostScript tiene una pila de retorno y un operando de pila, y tambin tiene un montn de grficos estado y un diccionario de pila. Forth utiliza dos pilas, una para pasar argumentos y una subrutina de direcciones de retorno. El uso de una pila de retorno es muy comn, pero el uso poco habitual de un argumento para una pila legible para humanos es el lenguaje de programacin Forth razn que se denomina una pila basada en el idioma. Muchas mquinas virtuales tambin estn orientadas hacia la pila, incluida la p-cdigo mquina y la mquina virtual Java. Casi todos los entornos de computacin de tiempo de ejecucin de memoria utilizan una pila especial PILA para tener informacin sobre la llamada de un procedimiento o funcin y de la anidacin con el fin de cambiar al contexto de la llamada a restaurar cuando la llamada termina. Ellos siguen un protocolo de tiempo de ejecucin entre el que llama y el llamado para guardar los argumentos y el valor de retorno en la pila. Pila es una forma importante de apoyar llamadas anidadas o a funciones recursivas. Este tipo de pila se utiliza implcitamente por el compilador para apoyar CALL y RETURN estados (o sus equivalentes), y no es manipulada directamente por el programador. Algunos lenguajes de programacin utilizar la pila para almacenar datos que son locales a un procedimiento. El espacio para los datos locales se asigna a los temas de la pila cuando el procedimiento se introduce, y son borradas cuando el procedimiento termina. El lenguaje de programacin C es generalmente aplicado de esta manera. Utilizando la misma pila de los datos y llamadas de procedimiento tiene importantes consecuencias para la seguridad (ver ms abajo), de los que un programador debe ser consciente, a fin de evitar la introduccin de graves errores de seguridad en un programa.
[editar] Solucionar problemas de bsqueda
La bsqueda de la solucin de un problema, es independientemente de si el enfoque es exhaustivo u ptimo, necesita espacio en la pila. Ejemplos de bsqueda exhaustiva mtodos son fuerza bruta y backtraking. Ejemplos de bsqueda ptima a explorar mtodos,son branch and bound y soluciones heursticas. Todos estos algoritmos utilizan pilas para recordar la bsqueda de nodos que se han observado, pero no explorados an. La nica alternativa al uso de una pila es utilizar la recursividad y dejar que el compilador sea recursivo (pero en este caso el compilador todava est utilizando una pila interna). El uso de pilas es frecuente en muchos problemas, que van desde almacenar la profundidad de los rboles hasta resolver crucigramas o jugar al ajedrez por ordenador. Algunos de estos problemas pueden ser resueltos por otras estructuras de datos como una cola.
[editar] Seguridad
La seguridad a la hora de desarrollar software usando estructuras de datos de tipo pila es un factor a tener en cuenta debido a ciertas vulnerabilidad que un uso incorrecto de stas puede originar en la seguridad de nuestro software o en la seguridad del propio sistema que lo ejecuta. Por ejemplo, algunos lenguajes de programacin usan una misma pila para almacenar los datos para un procedimientos y el link que permite retornar a su invocador. sto significa que el programa introduce y extrae los datos de la misma pila en la que se encuentra informacin crtica con las direcciones de retorno de las llamadas a procedimiento, supongamos que al introducir datos en la pila lo hacemos en una posicin errnea de manera que introducimos una datos de mayor tamao al soportado por la pila corrompiendo as las llamadas a procedimientos provocariamos un fallo en nuestro programa. sta tcnica usada de forma maliciosa (es similar pero en otro mbito al buffer overflow) permitira a un atacante modificar el funcionamiento normal de nuestro programa y nuestro sistema, y es al menos una tcnica til si no lo evitamos en lenguajes muy populares como el ejemplo C++.