Vous êtes sur la page 1sur 32

La pila

Estructuras de datos

LA PILA
La pila (stack) es una estructura ordenada de
elementos en la que se pueden insertar o
remover elementos por un extremo llamado la
cima de la pila (stack top).

Cima de
la pila

El apuntador de pila (stack pointer) seala al


elemento de la cima.
La pila puede carecer por completo de
elementos, en tal caso se le llama pila vaca.
En una pila vaca el apuntador de pila seala a
NULL.

Apuntador
de pila
Una pila

OPERACIONES BSICAS
Las operaciones bsicas de la pila son:
Apilar (push(s, i)) - inserta un nuevo elemento a la pila.
Desapilar (pop(s)) - remueve el elemento de la cima de la pila.

D
C
B
A

E
D
C
B
A

D
C
B
A

Pila antes de
Push(s, E)

Pila despus
de Push(s, E)

Pila antes de
i Pop(s)

C
B
A

i=D

Pila despus de
i Pop(s)

EVOLUCIN DE UNA PILA

I=POP(S)

PUSH(S,E) PUSH(S,F) I=POP(S)

I=POP(S)

I=POP(S)

F
D

sale E

sale C

sale D

entra E

entra F

sale F

OTRAS OPERACIONES
La funcin EMPTY(S) es verdadera si la pila est
vaca.
La operacin STACKTOP(S), que es equivalente a
un POP seguido de un PUSH.
I = POP(S);
PUSH(S,I);
determina el valor del elemento de la cima sin
removerlo.

ALGORITMO DE CHEQUEO DE
PARNTESIS
Algoritmo para checar parntesis. La expresin se almacena en la
cadena S.
1. VALIDO VERDADERO
2. I 1
3. CONTADOR 0
4. MIENTRAS VALIDO AND I <= LONGITUD(S) HACER
a. SI S[I] = '(' ENTONCES
1. CONTADOR CONTADOR + 1
b. SINO
1. SI S[I] = ')' ENTONCES
a. CONTADOR CONTADOR - 1
b. SI CONTADOR < 0 ENTONCES
1. VALIDO FALSO
c. I I + 1
5. SI CONTADOR <> 0 ENTONCES
a. VALIDO FALSO

Implementacin en C
int checa(char *s){
int i=0,contador=0,valido=1;
while(valido&&i<strlen(s)){
if(s[i]=='(')
contador++;
else
if(s[i]==')'){
contador--;
if(contador<0)
valido=0;
}
i++;
}
if(contador!=0)
valido=0;
return valido;
}

ALGORITMO DE CHEQUEO DE
PARNTESIS 2
Algoritmo para checar expresiones con parntesis bien construidas. Se
utiliza una pila P. La cadena se almacena en una variable S.
1. VALIDO VERDADERO
2. I 1
3. MIENTRAS VALIDO AND I <= LONGITUD(S)
a. SI (S[I] = '(') OR (S[I] = '[') OR (S[I] = '{') ENTONCES
1. PUSH(P,S[I])
b. SINO
1. SI (S[I] = ')') OR SI (S[I] = ']') OR SI (S[I] = '}') ENTONCES
a. SI EMPTY(P) ENTONCES
1. VALIDO FALSO
b. SINO
1. C POP(P)
2. SI NOT((C='(' AND S[I] = ')')OR(C='[' AND S[I] =']')
OR (C='{' AND S[I]= '}')) ENTONCES
a. VALIDO FALSO
c. I I + 1
4. SI NOT EMPTY(P) ENTONCES
a. VALIDO FALSO

Implementacin
int checa(char *s){
int i=0,valido=1;
pila p;
char c;
p.tope = -1;
printf("cad = %s\n",s);
while(valido&&i<strlen(s)){
if(s[i]=='('||s[i]=='[
||s[i]=='{')
push(&p,s[i]);
else
if(s[i]==')'||s[i]==']
||s[i]=='}'){
if(empty(p))
valido=0;
else{
c = pop(&p);

if(!(c=='('&&s[i]==')
||c=='['&&s[i]==']
||c=='{'&&s[i]=='}'))
valido = 0;
}
}
i++;
}
if(!empty(p))
valido=0;
return valido;
}

REPRESENTACIN
Una pila puede representarse con un registro, uno de los
campos es un entero usado como apuntador de pila y el
otro campo es un arreglo lineal de elementos de la pila.
Apuntador de pila
S:

Pila
'('

'['

'('

'{'

S.TOPE = apuntador de pila.


S.ITEM[S.TOPE] = elemento de la cima de la pila

OPERACIONES EMPTY Y POP


NOTA: Se supone una pila de caracteres

Funcin EMPTY(S:PILA) regresa BOOLEANO


1. SI S.TOPE = 0 ENTONCES
a. REGRESA VERDADERO
2. SINO
a. REGRESA FALSO
Funcin POP(S:PILA) regresa CARCTER
1. X S.ITEM[S.TOPE]
2. S.TOPE S.TOPE - 1
3. REGRESA X

OTRA VERSIN DE POP


Funcin POP(S:PILA) regresa CARCTER
1. SI EMPTY(S) ENTONCES
a. ERROR (bajo flujo, pila vaca)
2. SINO
a. X S.ITEM[S.TOPE]
b. S.TOPE S.TOPE - 1
c. REGRESA X

OPERACIN POPANDTEST
SUBRUTINA POPANDTEST(S: PILA;
BOOLEANO; X: CARCTER)
1. SI EMPTY(S) ENTONCES
a. BAJOFLUJO VERDADERO
2. SINO
a. BAJOFLUJO FALSO
b. X S.ITEM[S.TOPE]
c. S.TOPE S.TOPE - 1
d. REGRESA X

BAJOFLUJO:

OPERACIN PUSH
SUBRUTINA PUSH(S:PILA, X:CARACTER)
1. S.TOPE S.TOPE + 1
2. S.ITEM[S.TOPE] X
SUBRUTINA PUSH(S:PILA, X:CARACTER)
1. SI S.TOPE = STACKSIZE ENTONCES
a. ERROR (sobreflujo en la pila)
2. SINO
a. S.TOPE S.TOPE + 1
b. S.ITEM[S.TOPE] X

OPERACIN STACKTOP
FUNCION STACKTOP(S:PILA) regresa CARACTER
1. SI EMPTY(S) ENTONCES
a. ERROR (pila vacia)
2. SINO
a. REGRESA S.ITEM[S.TOP]

Operaciones de pila en C
#define TAMANOPILA 100
struct pila{
int tope;
char item[TAMANOPILA];
};
int empty(pila s){
if(s.tope==-1)
return 1;
else
return 0;
}

Operaciones de pila en C (cont.)


char pop(pila *s){
char x = s->item[s->tope];
s->tope--;
return x;
}
void push(pila *s,char x){
s->tope++;
s->item[s->tope] = x;
}

REPRESENTACIN DE EXPRESIONES
Entrefijo - el operador se escribe entre los dos operandos.
Es la normalmente utilizada en lgebra.
Prefijo - el operador se escribe antes de los operandos. Se
utiliza en algunos lenguajes de programacin como LISP.
Posfijo - el operador se escribe despus de los operandos.
Es utilizada en algunas calculadoras y computadoras.

EJEMPLOS DE EXPRESIONES
entrefijo
a+b

prefijo
+ab

posfijo
ab+

(a+b)*c
*+abc
(a-b)*(c-d) *-ab-cd

ab+c*
ab-cd-*

((a+b)*c(d-e))^
(f+g)

ab+c*de-fg+^

^-*+abcde+fg

EJEMPLO DE CONVERSIN
Conversin de entrefijo a prefijo
((a+b)*c-(d-e))^(f+g)
((+ab)*c-(-de))^(+fg)
((*(+ab)c)-(-de))^(+fg)
(-(*(+ab)c)(-de))^(+fg)
^(-(*(+ab)c)(-de))(+fg)
^-*+abc-de+fg

EJEMPLO DE CONVERSIN 2
Conversin de entrefijo a posfijo
((a+b)*c-(d-e))^(f+g)
((ab+)*c-(de-))^(fg+)
(((ab+)c*)-(de-))^(fg+)
(((ab+)c*)(de-)-)^(fg+)
((((ab+)c*)(de-)-)(fg+)^)
ab+c*de--fg+^

ALGORITMO DE EVALUACIN DE
POSFIJO
Algoritmo para evaluar una cadena en posfijo. Se suponen nmeros
de un solo dgito. La pila S guarda valores numricos.
1. MIENTRAS no se lea toda la cadena
a. Leer el siguiente smbolo y almacenarlo en simb
b. SI simb es un operando entonces
1. PUSH(S,SIMB)
c. SINO
1. OP2 POP(S)
2. OP1 POP(S)
3. VALOR resultado de aplicar simb a op2 y op1
4. PUSH(S,VALOR)
2. RESULTADO POP(S)

Ejemplo de evaluacin
235+4*+
Symb op2

=> 2 + (3 + 5)*4 = 2 + 32 = 34
op1

valor pila

2, 3

2, 3, 5

2, 8

2, 8, 4

32

2, 32

32

34

34

FUNCIN ES_DGITO
FUNCION ES_DIGITO ( C : CARCTER ) REGRESA
BOOLEANO
1. SI C >= '0' AND C <= '9' ENTONCES
a. REGRESAR VERDADERO
2. SINO
a. REGRESAR FALSO

FUNCIN OPER
FUNCION OPER(SIMB : CARACER, OP1, OP2 :
REAL ) REGRESA REAL
1. SI SIMB = '+' ENTONCES
a. REGRESA OP1 + OP2
2. SI SIMB = '-' ENTONCES
a. REGRESA OP1 - OP2
3. SI SIMB = '*' ENTONCES
a. REGRESA OP1 * OP2
4. SI SIMB = '/' ENTONCES
a. REGRESA OP1 / OP2
5. SI SIMB = '^' ENTONCES
a. REGRESA OP1 ^ OP2

ALGORITMO DE EVALUACIN
1. I 1
2. MIENTRAS I <= LONGITUD(CAD) HACER
a. SIMB CAD[I]
b. SI ES_DIGITO(SIMB) ENTONCES
1. PUSH(S, SIMB - 48)
c. SINO
1. OP2 POP(S)
2. OP1 POP(S)
3. VALOR OPER(SIMB, OP2, OP1)
4. PUSH(S,VALOR)
d. I I + 1
3. RESULTADO POP(S)

Evaluacin en C
float evalua(char *s){
int pos;
float op1,op2,valor;
pila p;
char c;
p.tope = -1;
for(pos=0; pos<strlen(s); pos++){
c = s[pos];
if(esdigito(c))
push(&p,c-'0');
else{
op1 = pop(&p);
op2 = pop(&p);
valor = oper(c,op1,op2);
push(&p,valor);
}
}
return pop(&p);
}

esdigito y oper en C
int esdigito(char c){
return c>='0' && c<='9';
}
float oper(char c,float op1, float op2){
switch(c){
case '+':return op1+op2;
case '-':return op2-op1;
case '*':return op1*op2;
case '/':return op2/op1;
}
}

CONVERSIN DE ENTREFIJO A POSFIJO


En la expresin a + b * c no puede procesarse el signo + hasta
haber procesado el signo * dado que tiene precedencia respecto
a +.
La funcin PRCD acepta dos caracteres y es verdadera si el
primer smbolo tiene precedencia respecto al segundo:
PRCD('*',' +') es VERDADERO
PRCD('+','+') es VERDADERO
PRCD('+', '*') es FALSO

ALGORITMO DE CONVERSIN
Algoritmo para convertir una cadena en entrefijo en posfijo. S es una pila de
operadores.
1. I 1
2. MIENTRAS I <= LONGITUD(CAD)HACER
a. SIMB CAD[I]
b. SI ES_OPERANDO(SIMB) ENTONCES
1.agregar a la cadena de posfijo
c. SINO
1.MIENTRAS(NOT EMPTY(S)AND PRCD(STACKTOP(S), SIMB ))HACER
a. SIMBTOPE POP(S)
b. agregar a la cadena de posfijo
2. PUSH(S,SIMB)
d. I I + 1
3. MIENTRAS NOT EMPTY(S)
a. SIMBTOPE POP(S)
b. agregar a la cadena de posfijo

USO DE PARNTESIS
Para incluir expresiones con parntesis basta con definir adecuadamente la
funcin PRCD. La siguiente tabla resume estos valores:
PRCD('(', op) = FALSO
para cualquier operador op
PRCD(op, '(') = FALSO
para cualquier operador op que no sea ')
PRCD(op, ')')=VERDADERO
para cualquier operador op que no sea ')
Adems hay que asegurar que el smbolo ')' no sea insertado en al pila y que
el parntesis que abra sea descartado. Para esto cambiamos la sentencia
PUSH por
SI (EMPTY(S) OR SIMB <> ')') ENTONCES
PUSH(S,SIMB)
SINO
SIMBTOPE = POP(S)
[extrae el parntesis que abre]

ALGORITO DE CONVERSIN FINAL


1. I 1
2. MIENTRAS I <= LONGITUD(CAD)
a. SIMB CAD[I]
b. SI ES_OPERANDO(SIMB) ENTONCES
1. agregar a la cadena de posfijo
c. SINO
1. POPANDTEST(S,SIMBTOPE,BAJOFLUJO)
2. MIENTRAS (NOT BAJOFLUJO AND PRCD(STACKTOP(S),SIMB))
a. agregar a la cadena de posfijo
b. POPANDTEST(S,SIMBTOPE,BAJOFLUJO)
3. SI NOT BAJOFLUJO ENTONCES
a. PUSH(S,SIMBTOPE)
4. SI (EMPTY(S) OR SIMB <> ')') ENTONCES
a. PUSH(S,SIMB)
5. SINO
a. SIMBTOPE = POP(S)
[extrae el parntesis que abre]
d. I I + 1
3. MIENTRAS NOT EMPTY(S)
a. SIMBTOPE POP(S)
b. agregar a la cadena de posfijo

Vous aimerez peut-être aussi