You are on page 1of 12

Leccion 3.1.

1 EJERCICIOS CON PILAS


Una pila es una estructura lineal de datos con la característica especial de que ahora, no
podemos hacer las inserciones y las eliminaciones en cualquier lugar, sino que obligatoriamente
las tenemos que hacer por un extremo de la lista. Ese extremo lo llamamos cima de la pila.

Esto supone que se procesen los elementos de la pila en orden inverso a su entrada en la
estructura, es decir, el primer elemento de la pila que usare será el último que ha entrado (LIFO).

Con una pila podemos hacer dos operaciones básicas, PUSH (meter) y POP (sacar).

Aparte de estas dos funciones se pueden definir otras como la de pila vacía o top, que me dice cual
es elemento que está en la cima de la pila pero sin sacarlo.

Se puede implementar con memoria estática (arrays) o con memoria dinámica (listas enlazadas).

Si utilizo un array, tendré que definir cual es el tamaño máximo del array, que será el de la pila, y
aparte tendré definida una variable cima que tendrá en cada momento el índice que corresponde
al elemento del array que está en la cima de la pila.

Pila = array [1..max_pila] de <info>


Cima: entero

Para señalar que la cima está vacía, cima es igual a 0 porque no tiene que apuntar a ningún
elemento.

Implementación de una pila con memoria estática:


Algoritmo prin_pila
Const
Max_pila = <max_pila>
Var
P: array [1..max_pila] de <info>
C: entero
Elem: <info>
Inicio
C <- 0
Leer (elem)
Si pila_vacia (C) = verdadero
Entonces escribir “Pila vacia”
Sino sacar (pila,c,elem)
Escribir “Elemento sacado”elem
Fin si
Fin

Funcion pila_vacia (cima: entero): booleano

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 1


Inicio
Si cima = 0
Entonces retorno verdadero
Sino retorno falso
Fin si
Fin

Procedimiento meter (ent-sal pila: array[1..max_pila] de <info>; cima: entero;


elem:<info>)
Inicio
si cima = max_pila
entonces escribir “Pila llena”
sino cima <- cima + 1
pila[cima] <- elem
fin si
Fin

Funcion cima_pila (pila: array[1..max_pila] de <info>; cima: entero):<info>


Inicio
Retorno pila[cima]
Fin

Procedimiento sacar (ent-sal pila: array[1..max_pila] de <info>; cima: entero;


ent-sal e: <info>)
Inicio
E <- cima_pila (cima,pila)
Cima <- cima – 1
Fin

Implementación de una pila con memoria dinámica:


Tipo nodo: registro
Info: <tipo>
Sig: puntero a nodo
Fin registro

Algoritmo manejo_pila
Var
Cima: puntero a nodo
Elem: <tipo>
Inicio
Cima <- nil
Meter (cima,elem)
Si pila_vacia (cima)
Entonces escribir “No hay memoria”
Sino sacar (cima,elem)

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 2


Escribir “Elemento sacado”elem
Fin si
Fin

Funcion pila_vacia (cima: puntero a nodo): booleano


Inicio
Si cima = nil
Entonces retorno verdadero
Sino retorno falso
Fin si
Fin

Procedimiento poner (ent-sal cima: puntero a nodo; elem: <tipo>)


Var
Nuevo: puntero a nodo
Inicio
Si DISP = nil
Entonces escribir “No hay memoria”
Sino nuevo <- DISP
DISP <- DISP ->sig
Nuevo->info <- elem
Nuevo->sig <- cima
Cima <- nuevo
Fin si
Fin

Funcion cima_pila (cima: puntero a nodo):<tipo>


Inicio
Retorno cima info
Fin

Procedimiento sacar (ent-sal cima: puntero a nodo; ent-sal elem: <tipo>)


Var
Borrado: puntero a nodo
Inicio
Elem <- cima_pila (cima)
Borrado <- cima
Cima <- cima->sig
Borrado->sig <- DISP
DISP <- borrado
Fin

Aplicaciones de las pilas

Un ejemplo tipico de uso de pilas, es las llamadas entre funciones. En este caso, els istema operativo
utiliza una pila en donde va guardando la direccion de retorno de cada una de estas llamadas.

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 3


En lo que se refiere a la resolución de problemas, muchas veces para plantear el problema
imaginamos objetos y acciones que se relacionan entre si.

Por ejemplo, un mesero tiene platos de colores apilados; de vez en cuando el que lava los
platos coloca un plato recién lavado sobre la pila de platos; y en otras ocaciones el mesero
toma el plato que esta hasta arriba y sirve ahí la comida que ha sido preparada por el cocinero
para posteriormente llevarla a su destino.

Si sabemos de qué color es la pila inicial de platos, y en qué momentos el que lava los platos
colocó platos sobre la pila(y claro, tambien sabemos el color de estos), y en qué momentos el
mesero retiró el plato que se encontraba hasta arriba; podemos saber de qué color será el
plato que le toca a cada cliente.

Una manera de saberlo podría ser, hacer una representación dramatica de los hechos; pero
esto no es necesario, ya que tambien podríamos tomar un lapiz y un papel, y escribir una lista
de los colores de los platos, posteriormente, ir escribiendo los colores de los platos que se
pusieron en la pila al final de la lista, y borrar el ultimo color de la lista cada que un plato se
retire.

No se necesita ser un gran matemático para pensar en hacer eso, sin embargo, en el
momento de querer implementar un programa en C que lo reprodusca, nos encontramos con
que no tenemos ninguna lista donde se coloquen y se quiten cosas del final, tenemos
solamente arreglos, variables, estructuras, apuntadores, etc. Claro que podemos simular esta
lista con las herramientas que nos proporciona C, asi pues, los objetos(como la pila de platos)
ligados a operaciones(como poner un nuevo plato o quitar un plato) que modifican al objeto
son llamados estructuras de datos.

Una definición sencilla de estructura de datos: unión de un conjunto de datos y funciones que
modifican dicho conjunto.

Es muy importante conocer las estructuras de datos mas comunes que se utilizan en la
programación, ya que la estructura de datos es vital para plantear el problema y al resolverlo,
poder implementar su solución eficazmente.

Pilas
Una pila, es la estructura de datos mencionada en el ejemplo anterior, es decir, un altero de
objetos. O mas formalmente, una estructura de datos en la cual solo se pueden hacer 2
operaciones: colocar un elemento al final, o quitar un elemento del final.
Lo unico que se puede hacer en una pila es colocar un objeto hasta arriba, o quitar el objeto
que esta arriba, ya que si se quita un objeto de abajo o del centro(lo mismo que si se intenta
añadir uno), la pila colapsaría.

Si queremos programar algo similar, lo mas obvio es guardar la información de la pila en un


arreglo.

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 4


Imaginemos que el restaurant tiene en total 10 platos(un restaurant bastante pobre), ello nos
indicaría que un arreglo de tamaño 10 podría guardar todos los platos sin temor a que el
tamaño del arreglo no alcance.

Suponiendo que inicialmente hay 2 platos, uno de color 1, y otro de color 2, el arreglo debería
lucir algo asi:

2100000000

Si repentinamente el que lava los platos pone un plato hasta arriba de color 2, luego de ello el
arreglo debería de lucir asi:

2120000000

Si luego pone hasta arriba un plato de color 3, entonces el arreglo debería de quedar asi:

2123000000

Pero si el mesero toma un plato de arriba, el arreglo estará de nuevo de esta manera:

2120000000

Si el mesero vuelve a tomar un plato de arriba, el arreglo quedará de esta manera:

2100000000

Para lograr esto, basta con declarar un arreglo y una variable.


Tal que el arreglo diga especificamente qué platos hay en la pila, y la variable cuántos platos
hay. Entonces, podemos declarar una pila de la siguiente manera(suponiendo que la pila es
de números enteros):

int pila[tamaño maximo];


int p=0;

Cada que queramos añadir un elemento en la parte superior de la pila, es suficiente con esta
línea de código:

pila[p++]=objeto;

Y cuando queramos retirar el elemento que este en la parte superior.

pila[p]= 0;

Por último, como cultura general, en ingles a la pila se le llama stack, a la operación de poner
un elemento en la parte superior se le llama push, y la de quitar un elemento se le llama pop.

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 5


Asi mismo, si la pila sobrepasa su tamaño máximo, el error devuelto es “stack overflow” o
“desbordamiento de pila”(ahora ya sabemos qué quieren decir algunos errores comunes que
saturan el monitor en pantallas azules).

Problema 1. Comprueba que es suficiente utilizar p-- en lugar de pila[p]=


0 para retirar un elemento de la pila.

Problema 2. En el álgebra, comunmente se utilizan signos de agrupación tales como ( ), [ ] o {


}, y se pueden utilizar para indicar el orden en que se realizarán las operaciones aritmeticas.
Ej. “[a(x+y)+c]d+(b(c+d))”, sin embargo, existen ciertas formas invalidas de utilizar dichos
signos de agrupación Ej. “[a+b)” ó “(a” ó “(b))” o tambien “([a+b)c]”. Es decir, cada signo que
“abre” debe tener un signo correspondiente que lo “cierre”, cada signo que “cierra” debe de
tener un signo correspondiente qué cerrar, y los signos no se pueden traslapar.
Escribe un programa, que dada una expresión algebrarica, determine si tiene o no error en los
signos de agrupación en tiempo lineal.

Problema 3. Una manera de encriptar mensajes(no muy segura), es colocar parentesis de


manera arbitraria, y todo lo que esta dentro de un parentesis, ponerlo al reves, por ejemplo
“Olimpiada de Informatica” se puede encriptar como “Olimpia(ad) de I(rofn)matica”, los
parentesis tambien se pueden anidar, es decir, otra forma de encriptar el mismo mensaje
podría ser “Olimpia(am(nfor)I ed (da))tica”. Escribe un programa, que dado un mensaje
encriptado, determine el mensaje original en tiempo lineal. (9° Olimpiada Mexicana de
Informática)

Problema 4. Hay n faros acomodados en línea recta, cada faro puede tener una altura
arbitraria, y además, cada faro brilla con cierta intensidad. La luz de cada faro ilumina
unicamente a los primeros faros en cada dirección cuyas alturas sean
estrictamente mayores a la del faro que emite la luz. La iluminación total de un faro, es la
suma de las luces que llegan al faro(sin incluir la propia).
Escribe un programa, que dadas las alturas de los n faros y las intensidades de cada uno,
determine cual es el faro mas iluminado en tiempo lineal. (USACO 2006)

Problema 5. Una cuadricula bicolorada, es aquella en la cual cada cuadro puede estar pintado
de color negro o de color blanco(todos los cuadros estan pintados de alguno de estos 2
colores). Puedes asumir que cada casilla de la cuadricula tiene area 1.
Escribe un programa, que dada una cuadricula bicolorada, determine el área del mayor
rectangulo (dentro de la cuadricula) pintado de un solo color. Tu programa deberá funcionar
en tiempo lineal (lineal en función del número de casillas de la cuadricula, NO en función de la
base o de la altura). (Croatian Olympiad in Informatics)

Problema 6. Considera el siguiente algoritmo recursivo para generar permutaciones de


arreglo[ ] desde inicio hasta fin:

1 funcion permuta(arreglo[ ], inicio, fin)


2 si inicio=fin entonces
3 imprime arreglo[ ];

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 6


4 fin_de_funcion;
5 para i=inicio hasta fin
6 intercambia(arreglo[inicio], arreglo[i]);
7 pemuta(arreglo[ ], inicio+1, fin);
8 intercambia(arreglo[inicio], arreglo[i]);
9 fin_de_funcion;

Escribe una función no recursiva que genere todas las permutaciones de arreglo[ ] desde
inicio hasta fin, con la misma complejidad que la función que se muestra

Ejemplo del Uso de Pilas en la solución de problemas


relacionados con la computación

Procesamiento de las llamadas a subrutinas y sus retornos

• Tenemos un procedimiento principal y tres rutinas

• Los retornos se deben hacer en orden inverso a las llamadas

• Entonces, las direcciones de retorno se van almacenando en una pila, y cada


vez que termina una ejecución se retorna a la dirección indicada en el tope de
la pila

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 7


Operaciones con las Pilas

• ADD (item, stack)  stack


Inserta item en stack, y devuelve el stack modificado

• DELETE (stack)  stack


Elimina el elemento del tope de stack, y devuelve el stack
modificado

• TOP (stack)  item


Devuelve el ítem ubicado en el tope de stack. No modifica stack

• ISEMPTY (stack)  boolean


Devuelve ‘true’ si stack está vacío, y “false” en caso contrario

Implementación de una pila

Supongamos que utilizamos un lenguaje que admite la definición de tipos


por medio de abstracción. Entonces, podríamos definir el tipo stack así:

type stack = abstracción

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 8


const N = 1000
var top: integer
var s: array [1..N] of integer

procedure ADD (item)


begin
if top ≥ N then
call STACK_FULL
else
top := top + 1
s [top] := item
end if
end

procedure DELETE ()
begin
if top ≤ 0 then
call STACK_EMPTY
else
top := top – 1
end if
end

procedure TOP ()
begin
if TOP = 0 then
return (error)
else
return (s [top])
end if
end
procedure ISEMPTY ()
begin
if top = 0 then
return (true)
else
return (false)
end if
end

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 9


begin { inicialización }
top := 0
end

Si queremos usar esta definición:


var p: snack
begin
p.ADD (1)
p.ADD (2)
p.ADD (3)
p.DELETE()
print (p.TOP())
end
Ejemplo en C++

/*PILA.C
Programa de Pilas.

El programa realiza lo siguiente:


Introducir datos a la pila
Sacar datos de la pila
Imprimir.

La pila es una subclase de lista lineal en la que las inserciones


y eliminaciones se realizan por un solo extremo y solamente el ultimo
elemento resulta accesible.
Esta estructura se conoce como LIFO last-in,first-out (ultimo en
entrar, primero en salir).
En una pila las inserciones y las supresiones se efectuan en la
misma punta de la pila llama Tope de pila.

Programa compilado con Turbo C version 2.01


*/
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<dos.h>

struct Pila{
char Dato;
struct Pila *Siguiente;
};

typedef enum{false,true}boolean;
enum{push=1,pop,salir};
void Push(struct Pila **,char);
char Pop(struct Pila **);
void Menu(void);

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 10


void Aplicacion(void);
boolean EstaVacia(struct Pila *);
void ImprimePila(struct Pila *);

int main(void)
{
char valor;
int opcion;
struct Pila *PtrPila;
PtrPila=NULL;
Menu();
scanf("%d",&opcion);
while(opcion!=salir){
switch(opcion){
case push:printf("Introduce una letra a la pila: ");
scanf("\n%c",&valor);
Push(&PtrPila,valor);
ImprimePila(PtrPila);
getch();
break;
case pop: if(!EstaVacia(PtrPila))
printf("El valor sacado de la pila es: %c.\n",Pop(&PtrPila));
ImprimePila(PtrPila);
getch();
break;
default: gotoxy(30,20);
printf("Opcion incorrecta.");
getch();
Menu();
break;
}
Menu();
scanf("%d",&opcion);
}
gotoxy(30,24);
printf("Fin de %s",__FILE__);
sleep(1);
return 0;
}

void Menu(void)
{
system("cls");
gotoxy(30,10);
printf("Escoje tu opcion:");
gotoxy(30,12);
printf("1.- Introduce un valor a la pila.");
gotoxy(30,13);
printf("2.- Saca un valor de la pila.");
gotoxy(30,14);
printf("3.- Salir del programa.");
gotoxy(30,15);
printf("? ");
}

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 11


void Push(struct Pila **Tope,char valor)
{
struct Pila *Nuevo;
Nuevo=(struct Pila *)malloc(sizeof(struct Pila));
if(Nuevo!=NULL){
Nuevo->Dato=valor;
Nuevo->Siguiente= *Tope;
*Tope=Nuevo;
}
else printf("%c no insertado. No hay memoria suficiente.\n",valor);
}

char Pop(struct Pila **Tope)


{
struct Pila *Temporal;
char ValorPop;
Temporal= *Tope;
ValorPop=(*Tope)->Dato;
*Tope=(*Tope)->Siguiente;
free(Temporal);
return ValorPop;
}

void ImprimePila(struct Pila *Actual)


{
if(Actual==NULL){
printf("La pila esta vacia.\n");
}
else{
printf("La pila es:\n");
while(Actual!=NULL){
printf("%c --> ",Actual->Dato);
Actual=Actual->Siguiente;
}
printf("NULL\n\n");
}
}

boolean EstaVacia(struct Pila *Tope)


{
if(Tope==NULL)
return true;
else
return false;
}

ESTRUCTURAS DE DATOS – LECCION 3.1.1 EJEMPLOS PILAS Página 12

You might also like