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

UNIVERSIDAD DE EL SALVADOR

FACULTAD DE INGENIERIA Y ARQUITECTURA


ESCUELA DE INGENIERIA DE SISTEMAS INFORMATICOS
ESTRUCTURAS DE DATOS

GUIA DE LABORATORIO No. 3


PILAS

Introduccin: Con esta gua se estudiar en detalle las formas de implementar las estructuras
de datos pila en diferentes lenguajes de programacin. La pila es una estructura de datos que
almacena y recupera sus elementos atendiendo un estricto orden. Las pilas se conocen tambin
como estructuras LIFO (Last-In, First-Out; Ultimo en Entrar Primero en Salir), todas las
inserciones y extracciones de elementos se realizan por un mismo extremo denominado tope de
la pila.

Objetivo: Que el estudiante conozca como se pueden utilizar las pilas en algunos problemas,
comprenda mejor el concepto de pila y practique el uso de la estructura en sus dos
implementaciones: esttico y dinmico, resolviendo algunos ejercicios.

I Pilas en el Lenguaje C

1. Pruebe el siguiente programa, en el cual se muestra el uso de pila implementada


utilizando un arreglo de 100 elementos. La funcin main() es una funcin sencilla
en la cual se le da al usuario la oportunidad de introducir/sacar 5 elementos de la
pila.

/* PILAS.C */

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define STACKSIZE 100

/* definicion de tipos de datos */


typedef char STACKELEMENT;
typedef struct {
int top;
STACKELEMENT items[STACKSIZE];
} STACK;
/*prototipos de funciones de la pila */
void Clear(STACK *);
int Empty(STACK *);
int Full(STACK *);
STACKELEMENT Pop(STACK *);
void Push(STACK *, STACKELEMENT);

void main() {
STACKELEMENT a;
int p, i;
STACK b;
STACK *c=&b;
b.top=-1;
clrscr();

ESTRUCTURAS DE DATOS CICLO II/2014


1
/*da la oportunidad de introducir o sacar elementos de la pila 5 veces*/
for (i=0; i<=4; i++) {
printf("Introducir o sacar de la pila 1/2");
scanf("%d", &p);
fflush(stdin);
if ( p == 1 ) {
printf("Elemento a introducir");
scanf("%c",&a);
Push(c, a);
printf("Elemento introducido con exito\n");
getch();
}
else {
if ( p == 2 ) {
if (Empty(c)) {
printf("Error: pila vacia.\n");
getch();
exit(1);
}
else {
a = Pop(c);
printf("Elemento sacado de la pila: %c\n", a);
getch();
}
} //Fin if ( p == 2 )
else
printf("La proxima vez debe digitar 1 o 2");
getch();
} // Fin else
} /* Fin del for */
} /* Fin de main */

/* limpia la pila */
void Clear(STACK * ps) {
ps->top= -1 ;
}
/* verifica si la pila esta vacia */
int Empty(STACK * ps) {
if (ps->top == -1)
return(TRUE);
else
return(FALSE);
}
/* verifica si la pila esta llena, si ya no se pueden introducir mas elementos en el arreglo */
int Full(STACK * ps) {
if (ps->top == STACKSIZE - 1)
return(TRUE);
else
return(FALSE);
}
/* introduce un elemento en la pila */
void Push(STACK * ps, STACKELEMENT x) {
if (Full(ps)) {
printf("%s","Pila desbordada");
exit(1); }
else

ESTRUCTURAS DE DATOS CICLO II/2014


2
ps->items[++(ps->top)]=x;
}
/* quita un elemento de la pila y lo devuelve */
STACKELEMENT Pop(STACK * ps) {
if (Empty(ps)) {
printf("%s","Pila subdesbordada");
exit(1); }
return(ps->items[(ps->top)--]);
}

2. Modifique el programa anterior para que la funcin main() sea mas flexible: que le
de la oportunidad al usuario de escoger cuantas operaciones de pila desea
realizar.
3. A continuacin se tiene un programa que origina una lnea de texto y utiliza una
pila para imprimir la lnea invertida.

/*Programa que origina una lnea de texto y utilice una pila


para imprimir la lnea invertida.*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define MAXCOLS 80
#define TRUE 1
#define FALSE 0

struct stack {
int tope;
char elementos[MAXCOLS];
};

int empty(struct stack *);


char pop(struct stack *);
void push(struct stack *, char);

void main() {
char linea[MAXCOLS];
char invert[MAXCOLS];
int pos=0, i;
struct stack pila;

pila.tope=-1;
while ((linea[pos++]=getchar()) != '\n');
linea[--pos]= '\0';
printf("La linea original es:\n %s", linea);
for (i=0; i<pos; i++)
push(&pila, linea[i]);
for (i=0; i<pos; i++)
invert[i]=pop(&pila);
invert[i] = '\0';
printf("\nLa linea invertida es: \n %s", invert);
getch();
}

int empty(struct stack *ps)


{

ESTRUCTURAS DE DATOS CICLO II/2014


3
return (ps->tope == -1);
}

char pop( struct stack *ps)


{
if (empty(ps))
{
printf("Subdesbordamiento de pila\n");
exit(1);
}
return ( ps->elementos[ps->tope--]);
}
void push(struct stack *ps, char a)
{
if (ps->tope == MAXCOLS - 1)
{
printf("Desbordamiento de pila\n");
exit(1);
}
ps->elementos[++ps->tope]=a;
}

4. Modifique el programa anterior para que tambin cuente el nmero de vocales que tiene
la lnea de texto.

5. Pruebe el siguiente programa (use extensin .cpp) que hace una conversin de interfija
a postfija. Los operandos validos son las letras de la A a la Z y los dgitos 0 a 9. Las
operaciones validas solo incluyen divisin ( / ), multiplicacin ( * ), suma ( + ) y resta ( - ).

# include <iostream.h> // por cout


# include <stdlib.h> // por malloc(), free()
# include <conio.h> // por clrscr()
# include <stdio.h> // por getchar()

#define MAXCOLS 80
#define TRUE 1
#define FALSE 0

struct stackNode {
int data;
stackNode *nextPtr;
};

typedef stackNode * STACKNODEPTR;

void postfix( char *, char * );


int isoperand(char);
void popandtest( STACKNODEPTR *, char *, int * );
int prcd( char , char );
void push (STACKNODEPTR *, char);
char pop (STACKNODEPTR *);
int empty(STACKNODEPTR);

void main()
{
char infix[MAXCOLS];

ESTRUCTURAS DE DATOS CICLO II/2014


4
char postr[MAXCOLS];

int pos = 0;
clrscr();
while ((infix[pos++] = getchar()) !='\n');
infix[--pos] = '\0';
cout<<"La expression original infija es "<< infix;
postfix(infix, postr);
cout<<postr<<endl;
getch();

} //fin de main

/*convierte de interfija a postfija sin tomar en cuenta parntesis.


tambin es solo valido para *,/,+,- */

void postfix ( char infix[], char postr[] )


{
int position, und;
int outpost = 0;
char topsymb = '+';
char symb;
STACKNODEPTR stackPtr = NULL;

for (position = 0; ( symb = infix [position]) != '\0'; position++)


if (isoperand(symb))
postr[outpost++] = symb;
else {
popandtest (&stackPtr, &topsymb, &und);
while ( !und && prcd(topsymb, symb)) {
postr[outpost++] = topsymb;
popandtest(&stackPtr, &topsymb, &und);
} // fin del while
if (!und)
push( &stackPtr, topsymb);
if (und || (symb != ')' ))
push( &stackPtr, symb);
else
topsymb = pop(&stackPtr);
} //fin del else
while ( !empty(stackPtr))
postr[outpost++] = pop(&stackPtr);
postr[outpost] = '\0';
} //fin de postfix

int empty( STACKNODEPTR ps)


{
return ps == NULL ;
}

int isoperand (char arg) {


if (( arg >= '0' && arg <= '9' ) || (arg >= 'A' && arg <= 'Z'))
return TRUE;
else
return FALSE;

ESTRUCTURAS DE DATOS CICLO II/2014


5
}

void popandtest (STACKNODEPTR *ps, char *px, int * pund) {


STACKNODEPTR tempPtr;
if (empty(*ps))
*pund = TRUE;
else
{
*pund = FALSE;
tempPtr = *ps;
*px = (*ps)->data;
*ps = (*ps)->nextPtr;
free(tempPtr);
}
} //fin de popandtest

// valido para precedencia de *,/,+,-


int prcd ( char a, char b )
{
if ( (a == '*' || a == '/' || a == '+' || a == '-' || a == ')' || a == '(') &&
(b == '*' || b == '/' || b == '+' || b == '-' || b == ')' || b == '('))
if ( a == '(' )
return FALSE;
else
if ( b == '(' )
return FALSE;
else
if ( a == '*' || a == '/' )
return TRUE;
else
if ( a == b )
return TRUE;
else
if ( b == ')' )
return TRUE;
else
return FALSE;
else
return -1;
}

void push (STACKNODEPTR *ps, char a)


{
STACKNODEPTR newPtr;
newPtr = (STACKNODEPTR) malloc(sizeof(stackNode));
if (newPtr != NULL) {
newPtr->data = a;
newPtr->nextPtr = *ps;
*ps = newPtr;
}
else
cout<<"No se pudo insertar. No hay memoria disponible\n";
}

char pop (STACKNODEPTR *ps)


{

ESTRUCTURAS DE DATOS CICLO II/2014


6
STACKNODEPTR tempPtr;
char a;

tempPtr = *ps;
a = (*ps)->data;
*ps = (*ps)->nextPtr;
free(tempPtr);
return a;

6. Programa que origina una lnea de texto y utiliza una pila para imprimir la lnea
invertida. Esta es la versin utilizando memoria dinmica.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define MAXCOLS 80

typedef struct nodo {


char dato;
struct nodo *siguiente;
}tiponodo;

typedef tiponodo *pNodo;


typedef tiponodo *Pila;

int empty(Pila *);


char pop(Pila *);
void push(Pila *, char);

void main() {
char linea[MAXCOLS];
char invert[MAXCOLS];
int pos=0, i;
Pila p1=NULL;

while ((linea[pos++]=getchar()) != '\n');


linea[--pos]='\0';
printf("La linea original es:\n %s", linea);
for (i=0; i<pos; i++)
push(&p1, linea[i]);
for (i=0; i<pos; i++)
invert[i]=pop(&p1);
invert[pos]='\0';
printf("\nLa linea invertida es: \n %s", invert);
getch();
}

int empty(Pila *ps)


{
return ((*ps)== NULL);
}

ESTRUCTURAS DE DATOS CICLO II/2014


7
void push(Pila *ps, char a)
{
pNodo nuevo;

nuevo = (pNodo) malloc(sizeof(tiponodo));


if (nuevo != NULL)
{
nuevo->dato = a;
nuevo->siguiente = *ps;
*ps = nuevo;
}
else
printf("No se pudo insertar el elemento. Falta de memoria\n");
}

char pop(Pila * ps)


{
pNodo temp;
char popvalue;

temp = *ps;
popvalue = (*ps)->dato;
*ps = (*ps)->siguiente;
free(temp);
return popvalue;
}

7. El siguiente programa lee una expresin en notacin interfija y la convierte a postfija.


Las operaciones validas son: potenciacin ( ^ ), divisin ( / ), multiplicacin ( * ), suma ( +
) y resta ( - ); es una variante del ejercicio 5 que si permite la potenciacin.

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char TipoElemento ;

typedef struct UnNodo {


TipoElemento e ;
struct UnNodo *sig ;
} Nodo ;

typedef Nodo Pila ;

int EsVaciaP(Pila *P){


return P == NULL ;
} // EsVaciaP

void VaciaP(Pila** P) {
*P = NULL ;
} // VaciaP

void AnadeP(Pila** P, TipoElemento a) {


Nodo * NuevoNodo;

ESTRUCTURAS DE DATOS CICLO II/2014


8
NuevoNodo = (Nodo*)malloc(sizeof(Nodo)) ;
NuevoNodo->e = a ;
NuevoNodo->sig=(*P) ;
*P=NuevoNodo ;
} //AnadeP

TipoElemento PrimeroP(Pila *P){


TipoElemento aux ;
if (EsVaciaP(P)) {
puts ("Se intenta extraer un elemento de una pila vacia") ;
exit(1) ;
}
aux = P->e ;
return aux ;
} // PrimeroP

void BorrarP(Pila** P) {
Pila *NuevoNodo ;
if (EsVaciaP(*P)) {
puts ("Se intenta extraer un elemento de una pila vacia") ;
exit(1) ;
}
NuevoNodo=(*P) ;
(*P) = NuevoNodo->sig ;
free(NuevoNodo) ;
} // BorrarP

int PrioridadDentro(char opdor) {


switch (opdor) {
case '(' : return 0 ;
case '^' : return 3 ;
case '/' : return 2 ;
case '*' : return 2 ;
case '+' : return 1 ;
case '-' : return 1 ;
} // fin switch
return 0 ;
} // PrioridadDentro

int PrioridadFuera(char opdor) {


switch (opdor) {
case '(' : return 5 ;
case '^' : return 4 ;
case '/' : return 2 ;
case '*' : return 2 ;
case '+' : return 1 ;
case '-' : return 1 ;
} // fin switch
return 0 ;
} // PrioridadFuera

int Operador (char ch) {


return ( ch == '(' || ch =='+' || ch =='-' || ch == '*' ||ch == '/' || ch == '^' ) ;
} // Operador

void Postfija (char Linea[80], char post[80]) {

ESTRUCTURAS DE DATOS CICLO II/2014


9
Pila *P ;
char ch, aux[2];
int i, Apilado ;
VaciaP(&P) ;
aux[1] = '\0' ;
post[0] = '\0' ;

for(i=0; i < strlen(Linea) ; i++)


if (Operador(Linea[i])) {
Apilado = 0 ;
while (!Apilado)
if (EsVaciaP(P)) {
AnadeP(&P, Linea[i]) ;
Apilado = 1 ;
}
else {
ch = PrimeroP(P) ;
if (PrioridadDentro(ch) >= PrioridadFuera(Linea[i])) {
aux[0] = ch ;
strcat(post, aux) ;
BorrarP(&P) ;
}
else {
AnadeP(&P, Linea[i]) ;
Apilado = 1 ;
}
} // else
} // if
else
if (Linea[i] == ')' ) {
ch = PrimeroP(P) ;
BorrarP(&P) ;
while (ch != '(' ) {
aux[0] = ch ;
strcat(post, aux) ;
ch = PrimeroP(P) ;
BorrarP(&P) ;
} // while
}
else {
aux[0] = Linea[i] ;
strcat(post, aux) ;
} // fin if
while (!EsVaciaP(P)) {
ch = PrimeroP(P) ;
BorrarP(&P) ;
aux[0] = ch ;
strcat(post, aux) ;
} // while
} // Postfija

void main (void) {


char post[80], Linea[80] ;
puts(" Expresion a pasar a PostFija\n") ;
gets(Linea) ;

ESTRUCTURAS DE DATOS CICLO II/2014


10
Postfija (Linea, post) ;
puts("\n Postfija \n") ;
puts(post) ;
puts("\n\tPresione cualquier tecla para continuar") ;
getch() ;
} // void main

Ejercicios Propuestos en C:

1. Escriba un programa que utilice una pila para determinar si una cadena es un
palndromo (es decir, si la cadena se deletrea en forma idntica hacia delante y hacia
atrs). El programa deber ignorar espacios y puntuaciones.
2. Escriba un programa en C para convertir una cadena prefija a posfija.
3. Escriba una rutina prefix que acepte una cadena interfija y cree la forma prefija de esta
cadena, suponiendo que la cadena se lee de derecha a izquierda y que la cadena prefija
se crea de derecha a izquierda.
4. Escriba la rutina reduce en C y que acepte una cadena interfija y forme una cadena
interfija equivalente quitando todos los parntesis superfluos.
5. Repita los ejercicios del 1 al 4 utilizando memoria dinmica.
6. Modifique el programa que aparece en el ejercicio 7, escribiendo una funcin que reciba
una expresin en notacin postfija y la evalu. Utilice el siguiente cdigo.

float valor (char c) {


return (float) c ;
} // valor

float evaluar (char post[80]) {


float valor1, valor2, valor3 ;
int i ;
Pila *P ;
VaciaP(&P) ;
for(i=0 ; i<strlen(post); i++)
if (Operador(post[i])) {
valor2 = PrimeroP(P) ;
BorrarP(&P) ;
valor1 = PrimeroP(P) ;
BorrarP(&P) ;
switch (post[i]) {
case '^' : valor3 = pow(valor1, valor2) ; break ;
case '/' : valor3 = valor1 / valor2 ; break ;
case '*' : valor3 = valor1 * valor2 ; break ;
case '+' : valor3 = valor1 + valor2 ; break ;
case '-' : valor3 = valor1 - valor2 ;
} // switch
AnadeP(&P, valor3) ;
}
else {
valor3 = valor(post[i]) ;
AnadeP(&P, valor3) ;
}
valor1 = PrimeroP(P) ;
BorrarP(&P) ;
return valor1 ;
} // evaluar

ESTRUCTURAS DE DATOS CICLO II/2014


11
II Pilas en el Lenguaje JAVA

Para los programas de esta parte de la gua utilice JGRASP

Edite el siguiente programa (El nombre del archivo deber ser Pila.java), tal como se muestra en
la siguiente figura.

public class Pila {


// Atributos de la Clase
int tope=-1;
int vec[];

// Constructor de la Clase
public Pila(int max) {
vec=new int [max];
}

// Metodos de la Clase
public boolean llena() {
if (tope==vec.length-1)
return true;
else
return false;
}

ESTRUCTURAS DE DATOS CICLO II/2014


12
public boolean vacia() {
if (tope==-1)
return true;
else
return false;
}

public void push(int dato) {


if (llena()== true)
System.out.println("Overflow");
else
vec[++tope]= dato;
}

public int pop() {


int aux;
if (vacia()== true) {
System.out.println("La Pila esta Vacia");
return -1;
}
else {
aux=vec[tope--];
return aux ;
}
}

public void Imprime_Datos() {


if(vacia()== true)
System.out.println("La Pila esta Vacia, ingrese datos primero:");
else
for(int Contador=0; Contador <= tope; Contador++)
System.out.println("Los valores de la pila son: "+ vec[Contador]);
}
}

Guarde el archivo con el siguiente smbolo

Para Compilar un programa java con el JGRASP utilice el smbolo

Ahora proceda a editar el siguiente programa

import javax.swing.JOptionPane ;

public class UsaPila{

public static void main (String args[]) {


int stacksize = 5 ;
String s_numero ;
int n_numero, cont = 0 ;
Pila Stack = new Pila(stacksize) ;

ESTRUCTURAS DE DATOS CICLO II/2014


13
do {
s_numero = JOptionPane.showInputDialog(null,
"Introduzca un numero entero positivo menor de 700") ;
n_numero = Integer.parseInt(s_numero) ;
Stack.push(n_numero) ;
cont++ ;
} while (cont < stacksize) ;
Stack.Imprime_Datos();
n_numero = Stack.pop() ;
System.out.println("\nValor extraido de la pila " + n_numero) ;
n_numero = Stack.pop() ;
System.out.println("Valor extraido de la pila " + n_numero + "\n") ;

Stack.Imprime_Datos();
}

} // UsaPila

El nombre del archivo deber ser UsaPila.java, ahora procesa a Compilar el programa
utilizando el icono

Ahora proceda a Ejecutar el programa utilizando el siguiente smbolo

Preguntas

Identifique en el programa Pila.java lo siguiente:

1. Cuales son los Atributos de la Clase.


2. Cuales son los Mtodos o Funciones de la Clase.
3. Como Funcionan los mtodos push y pop de la clase Pila

Explique en el programa UsaPila.java como es el proceso de invocacin de los


mtodos o funciones push, pop e Imprime_Datos.

Ejercicios Propuestos en JAVA:

Traduzca los ejercicios 1 y 3 de la primera parte al lenguaje de programacin Java.

ESTRUCTURAS DE DATOS CICLO II/2014


14

Вам также может понравиться