Download - La Pila (Stack)
Estructuras de Datos
Ricardo Ruiz Rodríguez
21
Capítulo 2. LA PILA (STACK).
2.1 Definición y ejemplos. Una pila es un conjunto ordenado de elementos en el cual se
pueden agregar y eliminar elementos de un extremo, el cual es
llamado el tope de la pila.
La pila es un objeto dinámico en constante cambio.
La definición de pila especifica que un solo extremo de la pila
se designa como tope.
Estructuras de Datos
Ricardo Ruiz Rodríguez
22
Pueden colocarse nuevos elementos en el tope de la pila o se
pueden quitar elementos de él.
La característica más importante de la pila es que el último
elemento insertado en ella es el primero en suprimirse.
Por esta razón, una pila se denomina como una estructura LIFO
(Last In First Out) en la cual, el último elemento insertado, será el
primero en ser eliminado.
Estructuras de Datos
Ricardo Ruiz Rodríguez
23
Tabla 1. Crecimiento y decrecimiento de una Pila.
→ G → I
→ F F → F → H H
→ E E E E → E E E
→ D D D D D D D D
C C C C C C C C
B B B B B B B B
A A A A A A A A
Estructuras de Datos
Ricardo Ruiz Rodríguez
24
2.2 Funciones primitivas. Las funciones básicas definidas sobre una pila son push y pop.
La función push inserta un nuevo elemento en el tope de la pila.
La función pop elimina el elemento indicado por el tope de la
pila.
Existen otras funciones útiles al usar pilas, por ejemplo, antes
de aplicar la operación pop a una pila, se debe verificar que la pila
no esté vacía.
Así, la función isEmpty determina si una pila está o no vacía.
Estructuras de Datos
Ricardo Ruiz Rodríguez
25
Otra operación que puede ejecutarse sobre una pila es
determinar cuál es el elemento que se encuentra en el tope de la
pila pero sin eliminarlo. Esta función puede llamarse stacktop.
2.3 Representación de pilas en C. Hay varias formas de representar una pila en C y cada una de
ellas es sólo una implementación del concepto introducido en la
sección anterior.
Aunque un arreglo no es una pila, bien puede ser usado para
representar una.
(Ejemplo del arreglo implementando una pila).
Estructuras de Datos
Ricardo Ruiz Rodríguez
26
Una pila es fundamentalmente un objeto dinámico cuyo tamaño
se modifica en forma continua conforme se agregan y remueven
elementos.
(Ejemplo de una pila dinámica).
Un programador siempre debe preocuparse por la legibilidad
del código que produce.
2.4 Ejemplos clásicos del uso de pilas. Esta sección revisa dos ejemplos clásicos del uso de pilas, no
son las únicas aplicaciones que se tienen de este tipo de estructura
de datos, pero sí son de los más representativos.
Estructuras de Datos
Ricardo Ruiz Rodríguez
27
2.4.1 Análisis básico de expresiones. Considérese la siguiente expresión matemática:
−
+
−+
∗−
2543
7y
jyxx
Cuya representación “lineal” es:
• 7 – ((x * ((x + y) / (j - 3)) + y) / (4 – 5/2)).
¿Cómo saber si la expresión está correctamente balanceada en
cuanto a paréntesis se refiere?
Estructuras de Datos
Ricardo Ruiz Rodríguez
28
Considérese ahora la siguiente expresión matemática:
[ ]( ) ( )[ ]{ }[ ]( )( )( )nlkjh
edcbayx−−−−
+−∗+−+
Cuya representación “lineal” es:
• {x + (y – [a + b]) * c – [(d + e)]} / (h – (j – (k – [l - n]))).
¿Cómo saber si la expresión está correctamente balanceada en
cuanto a símbolos de agrupación se refiere?
¿Cómo saber que un símbolo de agrupación está cerrando a su
correspondiente símbolo de apertura?
Considere el siguiente algoritmo:
Estructuras de Datos
Ricardo Ruiz Rodríguez
29
valid = true; s = the empty stack; while(not end of string){ read the next symbol of the string; if(symbol == ‘(’ || symbol == ‘[’ || symbol == ‘{’) push(s, symbol); else if(symbol == ‘)’ || symbol == ‘]’ || symbol == ‘}’){ if(isEmpty(s)) valid = false; else{ i = pop(s); if(i is not equivalent to symbol) valid = false; } }
Estructuras de Datos
Ricardo Ruiz Rodríguez
30
} /* while’s */ if(!isEmtpy(s)) valid = false; if(valid) printf(“The string is valid\n”); else printf(“The string is invalid\n”);
2.4.2 Notación interfija, postfija y prefija. Considere la suma de dos números A y B.
Aplicar el operador “+” a los operandos A y B, y escribir la
suma como A + B tiene el nombre de representación interfija.
Estructuras de Datos
Ricardo Ruiz Rodríguez
31
Hay otras dos notaciones alternas para expresar la suma de A y
B usando los mismos símbolos A, B y +:
• + A B representación prefija.
• A B + representación postfija.
Los prefijos “pre”, “pos” e “inter” hacen referencia a la
posición relativa del operador en relación a los operandos.
Una función en C para retornar la suma de dos argumentos
invocada mediante add(s, b) utiliza notación prefija, ya que el
operador add precede a los operandos.
Considere la siguiente expresión:
Estructuras de Datos
Ricardo Ruiz Rodríguez
32
• A + B * C indica implícitamente A + (B * C).
Suponga que se desea convertir la expresión anterior a su
representación en postfija. Entonces, aplicando las reglas de
precedencia, primero se convierte la parte de la expresión que se
evalúa primero:
• A + (B * C) forma interfija.
• A + (BC *) se convierte la multiplicación.
• A (BC *) + convierte la suma.
• A B C * + representación postfija.
Estructuras de Datos
Ricardo Ruiz Rodríguez
33
Las únicas reglas que deben recordarse durante el proceso de
conversión son las siguientes:
1.Las operaciones con mayor precedencia se convierten
primero.
2.Después de que una parte de la expresión se ha convertido a
postfija, se considerará como un operando único.
Ejemplo:
1.(A + B) * C forma interfija.
2.(A B +) * C se convierte la adición.
3.(A B +) C * convierte la multiplicación.
Estructuras de Datos
Ricardo Ruiz Rodríguez
34
4.A B + C * representación postfija.
Ejercicio: Convertir las siguientes expresiones en su
representación postfija:
1 . A + B
2 . A + B - C
3 . ( A + B ) * ( C - D )
4 . A $ B * C – D + E / F / ( G + H )
5 . ( ( A + B ) * C – ( D - E ) ) $ ( F + G )
6 . A – B / ( C * D $ E )
Estructuras de Datos
Ricardo Ruiz Rodríguez
35
El signo de $ en las expresiones anteriores, representa el
símbolo de exponenciación y es el de más alta precedencia.
Las reglas para convertir una expresión de interfija a prefija son
idénticas. El único cambio es que el operador se coloca antes de los
operandos en lugar de después de ellos.
Ejercicio: Convierta las expresiones anteriores a su
representación prefija.
En base a los ejercicios anteriores, debe observarse que la
representación prefija no siempre es una imagen reflejo de la
representación postfija.
Estructuras de Datos
Ricardo Ruiz Rodríguez
36
El orden de los operadores en las expresiones postfijas
determina el orden real de las operaciones al evaluar la expresión,
haciendo innecesario el uso de paréntesis.
Ejercicio: Crear un algoritmo, así como su implementación,
para convertir una expresión interfija en:
1.Postfija.
2.Prefija.
Con valores concretos en las expresiones postfijas. ¿Cómo
evaluar una expresión postfija?
Considere el siguiente algoritmo:
Estructuras de Datos
Ricardo Ruiz Rodríguez
37
Algoritmo para evaluar una expresión postfija:
opndstack = the empty satck; while(not end of input){ symbol = next input character; if(symbol is an operand) push(opndstack, symbol); else{ opnd2 = pop(opndstack); opnd1 = pop(opndstack); value = opnd1 symbol opnd2; push(opndstack, value); } } return pop(opndstack);
Estructuras de Datos
Ricardo Ruiz Rodríguez
38
Solución a los ejercicios de conversión:
Prefija: Postfija:
1. + A B A B +
2. - + A B C A B + C -
3. * + A B - C D A B + C D - *
4. + - * $ A B C D / / E F + G H A B $ C * D - E F / G H + / +
5. $ - * + A B C - D E + F G A B + C * D E - - F G + $
6. - A / B * C $ D E A B C D E $ * / -