Download - La pila
![Page 1: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/1.jpg)
La pila
Estructuras de datos
![Page 2: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/2.jpg)
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).
El apuntador de pila (stack pointer) señala al elemento de la cima.
La pila puede carecer por completo de elementos, en tal caso se le llama pila vacía. En una pila vacía el apuntador de pila señala a NULL. Una pila
Cima de la pila
Apuntador de pila
LA PILA
![Page 3: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/3.jpg)
Las operaciones básicas 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.
ABCD
Pila antes de Push(s, E)
ABCD
Pila después de Push(s, E)
E
ABCD
Pila antes de i Pop(s)
ABC
Pila después de i Pop(s)
i=D
OPERACIONES BÁSICAS
![Page 4: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/4.jpg)
A
B
C
D
A
B
C
A
B
C
E
A
B
C
F
A
B
C
E
A
B
C
A
B
I=POP(S) PUSH(S,E) PUSH(S,F)
E
I=POP(S) I=POP(S) I=POP(S)
sale D sale F sale E sale Centra E entra F
EVOLUCIÓN DE UNA PILA
![Page 5: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/5.jpg)
La función EMPTY(S) es verdadera si la pila está vacía.
La operación 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.
OTRAS OPERACIONES
![Page 6: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/6.jpg)
Algoritmo para checar paréntesis. La expresión se almacena en la cadena S.1. VALIDO VERDADERO2. I 13. CONTADOR 04. MIENTRAS VALIDO AND I <= LONGITUD(S) HACER
a. SI S[I] = '(' ENTONCES1. CONTADOR CONTADOR + 1
b. SINO1. SI S[I] = ')' ENTONCES
a. CONTADOR CONTADOR - 1b. SI CONTADOR < 0 ENTONCES
1. VALIDO FALSOc. I I + 1
5. SI CONTADOR <> 0 ENTONCESa. VALIDO FALSO
ALGORITMO DE CHEQUEO DE PARÉNTESIS
![Page 7: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/7.jpg)
Implementación 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;}
![Page 8: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/8.jpg)
Algoritmo para checar expresiones con paréntesis bien construidas. Se utiliza una pila P. La cadena se almacena en una variable S.1. VALIDO VERDADERO2. I 13. 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) ENTONCES1. 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 + 14. SI NOT EMPTY(P) ENTONCES
a. VALIDO FALSO
ALGORITMO DE CHEQUEO DE PARÉNTESIS 2
![Page 9: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/9.jpg)
Implementación
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;}
![Page 10: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/10.jpg)
'(' '[' '(' '{'4S:
Apuntador de pila Pila
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.
S.TOPE = apuntador de pila.S.ITEM[S.TOPE] = elemento de la cima de la pila
REPRESENTACIÓN
![Page 11: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/11.jpg)
Función EMPTY(S:PILA) regresa BOOLEANO1. SI S.TOPE = 0 ENTONCES
a. REGRESA VERDADERO2. SINO
a. REGRESA FALSO
Función POP(S:PILA) regresa CARÁCTER1. X S.ITEM[S.TOPE]2. S.TOPE S.TOPE - 13. REGRESA X
NOTA: Se supone una pila de caracteres
OPERACIONES EMPTY Y POP
![Page 12: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/12.jpg)
Función POP(S:PILA) regresa CARÁCTER1. SI EMPTY(S) ENTONCES
a. ERROR (‘bajo flujo, pila vacía’)2. SINO
a. X S.ITEM[S.TOPE]b. S.TOPE S.TOPE - 1c. REGRESA X
OTRA VERSIÓN DE POP
![Page 13: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/13.jpg)
SUBRUTINA POPANDTEST(S: PILA; BAJOFLUJO: BOOLEANO; X: CARÁCTER)1. SI EMPTY(S) ENTONCES
a. BAJOFLUJO VERDADERO2. SINO
a. BAJOFLUJO FALSOb. X S.ITEM[S.TOPE]c. S.TOPE S.TOPE - 1d. REGRESA X
OPERACIÓN POPANDTEST
![Page 14: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/14.jpg)
SUBRUTINA PUSH(S:PILA, X:CARACTER)1. S.TOPE S.TOPE + 12. 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 + 1b. S.ITEM[S.TOPE] X
OPERACIÓN PUSH
![Page 15: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/15.jpg)
FUNCION STACKTOP(S:PILA) regresa CARACTER1. SI EMPTY(S) ENTONCES
a. ERROR (‘pila vacia’)2. SINO
a. REGRESA S.ITEM[S.TOP]
OPERACIÓN STACKTOP
![Page 16: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/16.jpg)
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;}
![Page 17: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/17.jpg)
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;}
![Page 18: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/18.jpg)
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 programación como LISP.
Posfijo - el operador se escribe después de los operandos. Es utilizada en algunas calculadoras y computadoras.
REPRESENTACIÓN DE EXPRESIONES
![Page 19: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/19.jpg)
EJEMPLOS DE EXPRESIONES
entrefijo prefijo posfijo
a+b +ab ab+
(a+b)*c *+abc ab+c*
(a-b)*(c-d) *-ab-cd ab-cd-*
((a+b)*c- (d-e))^ (f+g)
^-*+abc-de+fg
ab+c*de--fg+^
![Page 20: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/20.jpg)
EJEMPLO DE CONVERSIÓN
((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
Conversión de entrefijo a prefijo
![Page 21: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/21.jpg)
((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+^
Conversión de entrefijo a posfijo
EJEMPLO DE CONVERSIÓN 2
![Page 22: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/22.jpg)
ALGORITMO DE EVALUACIÓN DE POSFIJO
Algoritmo para evaluar una cadena en posfijo. Se suponen números de un solo dígito. La pila S guarda valores numéricos.1. MIENTRAS no se lea toda la cadena
a. Leer el siguiente símbolo y almacenarlo en simbb. 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 op14. PUSH(S,VALOR)
2. RESULTADO POP(S)
![Page 23: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/23.jpg)
Ejemplo de evaluación2 3 5 + 4 * + => 2 + (3 + 5)*4 = 2 + 32 = 34
Symb op2 op1 valor pila
2 2
3 2, 3
5 2, 3, 5
+ 5 3 8 2, 8
4 5 3 8 2, 8, 4
* 4 8 32 2, 32
+ 32 2 34 34
![Page 24: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/24.jpg)
FUNCIÓN ES_DÍGITO
FUNCION ES_DIGITO ( C : CARÁCTER ) REGRESA BOOLEANO1. SI C >= '0' AND C <= '9' ENTONCES
a. REGRESAR VERDADERO2. SINO
a. REGRESAR FALSO
![Page 25: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/25.jpg)
FUNCIÓN OPER
FUNCION OPER(SIMB : CARACER, OP1, OP2 : REAL ) REGRESA REAL1. SI SIMB = '+' ENTONCES
a. REGRESA OP1 + OP22. SI SIMB = '-' ENTONCES
a. REGRESA OP1 - OP23. SI SIMB = '*' ENTONCES
a. REGRESA OP1 * OP24. SI SIMB = '/' ENTONCES
a. REGRESA OP1 / OP25. SI SIMB = '^' ENTONCES
a. REGRESA OP1 ^ OP2
![Page 26: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/26.jpg)
ALGORITMO DE EVALUACIÓN
1. I 12. 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 + 13. RESULTADO POP(S)
![Page 27: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/27.jpg)
Evaluación en Cfloat 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);}
![Page 28: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/28.jpg)
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; }}
![Page 29: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/29.jpg)
CONVERSIÓN DE ENTREFIJO A POSFIJO
En la expresión a + b * c no puede procesarse el signo + hasta haber procesado el signo * dado que tiene precedencia respecto a +.
La función PRCD acepta dos caracteres y es verdadera si el primer símbolo tiene precedencia respecto al segundo:
PRCD('*',' +') es VERDADERO
PRCD('+','+') es VERDADERO
PRCD('+', '*') es FALSO
![Page 30: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/30.jpg)
ALGORITMO DE CONVERSIÓN
Algoritmo para convertir una cadena en entrefijo en posfijo. S es una pila de operadores.1. I 12. 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 + 13. MIENTRAS NOT EMPTY(S)
a. SIMBTOPE POP(S)b. agregar a la cadena de posfijo
![Page 31: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/31.jpg)
USO DE PARÉNTESIS
Para incluir expresiones con paréntesis basta con definir adecuadamente la función PRCD. La siguiente tabla resume estos valores:PRCD('(', op) = FALSO para cualquier operador opPRCD(op, '(') = FALSO para cualquier operador op que no sea ')’PRCD(op, ')')=VERDADERO para cualquier operador op que no sea ')’
Además hay que asegurar que el símbolo ')' no sea insertado en al pila y que el paréntesis que abra sea descartado. Para esto cambiamos la sentencia PUSH por
SI (EMPTY(S) OR SIMB <> ')') ENTONCESPUSH(S,SIMB)
SINO
SIMBTOPE = POP(S) [extrae el paréntesis que abre]
![Page 32: La pila](https://reader035.vdocuments.co/reader035/viewer/2022062423/568144e8550346895db1b8cb/html5/thumbnails/32.jpg)
ALGORITO DE CONVERSIÓN FINAL1. I 12. 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 paréntesis que abre] d. I I + 13. MIENTRAS NOT EMPTY(S) a. SIMBTOPE POP(S) b. agregar a la cadena de posfijo