Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
• El TAD Pila
• Estructura de datos y primitivas de Pila
• Implementación en C de Pila
• Implementación con top de tipo entero
Programación II • Ejemplos de aplicación de Pila
Tema 2. Pilas • Balanceo de paréntesis
• Evaluación de expresiones posfijo
• Conversión entre notaciones infijo, posfijo y prefijo
Contenidos 2
El TAD Pila 3
• Anexo
• Implementación con top de tipo puntero
Contenidos 6
Estructura de datos y primitivas de Pila 7
• Balanceo de paréntesis 5
• EdD en C
• datos: en este tema será un array de punteros: Elemento *datos[];
• top: en este tema se declarará de 2 maneras (versiones) distintas
• Primitivas
• V1: Como un entero: int top;
Pila pila_crear(): crea, inicializa y devuelve una pila • V2: Como un puntero a un elemento del array: Elemento **top;
pila_liberar(Pila s): libera (la memoria ocupada por) la pila
7 7
boolean pila_vacia(Pila s): devuelve true si la pila está vacía y false si no 6 6
boolean pila_llena(Pila s): devuelve true si la pila está llena y false si no x x
5 5
Contenidos 10
Implementación en C de Pila 11
• El TAD Pila
• Estructura de datos y primitivas de Pila • Implementación con top de tipo entero
• Asumimos la existencia del TAD Elemento
• Implementación en C de Pila 7
• EdD de Pila mediante un array
• Implementación con top de tipo entero 6
// En pila.h x
5
• Ejemplos de aplicación de Pila typedef struct _Pila Pila;
4 x
• Balanceo de paréntesis // En pila.c 3
#define PILA_MAX 8 x
• Evaluación de expresiones posfijo struct _Pila { 2
x
Elemento *datos[PILA_MAX];
• Conversión entre notaciones infijo, posfijo y prefijo 1
int top; x
}; 4 0
• Implementación con top de tipo entero • Implementación con top de tipo entero
• Asumimos la existencia del TAD Elemento que, entre otras, • Asumimos la existencia del TAD Elemento que, entre otras,
tiene asociadas las primitivas liberar y copiar: tiene asociadas las primitivas liberar y copiar:
void elemento_liberar(Elemento *pe); void elemento_liberar(Elemento *pe);
Elemento *elemento_copiar(const Elemento *pe); Elemento *elemento_copiar(const Elemento *pe);
Implementación en C de Pila 14
Implementación en C de Pila 15
• Implementación con top de tipo entero • Implementación con top de tipo entero
vacía Existe: void elemento_liberar(Elemento *pe);
Pila *pila_crear() {
Pila *ps = NULL; 7 7
int i;
6 void pila_liberar(Pila *ps) { 6
ps = (Pila *) malloc(sizeof(Pila)); int i;
5 5
if (ps == NULL) {
return NULL; 4 if (ps != NULL) { 4 x
} for (i=0; i<=ps->top; i++) {
3 3
elemento_liberar(ps->datos[i]); x
for (i=0; i<PILA_MAX; i++) { // Bucle opcional } 2
2
ps->datos[i] = NULL; free(ps); x
1 } 1
}
-1 0
}
4 0 x
ps->top = -1;
top datos top datos x
return ps;
}
ps ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 16
Implementación en C de Pila 17
• Implementación con top de tipo entero • Implementación con top de tipo entero
Existe: void elemento_liberar(Elemento *pe); Existe: void elemento_liberar(Elemento *pe);
7 7
ps ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 18
Implementación en C de Pila 19
• Implementación con top de tipo entero • Implementación con top de tipo entero
• Asumimos la existencia del TAD Elemento que, entre otras, boolean pila_vacia(const Pila *ps) {
if (ps == NULL) { vacía
tiene asociadas las primitivas liberar y copiar: return NULL_BOOLEAN;
void elemento_liberar(Elemento *pe); } 7
Elemento *elemento_copiar(const Elemento *pe); 6
if (ps->top == -1) {
• Primitivas (prototipos en pila.h) return TRUE; 5
Pila *pila_crear(); 7 }
return FALSE; 4
void pila_liberar(Pila *ps); 6
} 3
boolean pila_vacia(const Pila *ps); x
5
boolean pila_llena(const Pila *ps); 2
status pila_push(Pila *ps, const Elemento *pe); 4 x
1
Elemento *pila_pop(Pila *ps); 3 x Nota: -1 0
• Estructura de datos (en pila.c) 2 Llamaremos a pila_vacia antes de hacer pop, comprobando si hay top datos
x
struct _Pila { 1 elementos en la pila. Si la pila está vacía, no llamaremos a pop.
Elemento *datos[PILA_MAX]; x Por eso, si ps es NULL, aquí detectamos el error y devolvemos
int top; 4 0
TRUE indicando que la pila “está” vacía, con el fin de que luego no ps
}; top datos se haga pop.
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 20
Implementación en C de Pila 21
• Implementación con top de tipo entero • Implementación con top de tipo entero
boolean pila_llena(const Pila *ps) { llena x • Asumimos la existencia del TAD Elemento que, entre otras,
if (ps == NULL) {
return NULL_BOOLEAN; 7
x tiene asociadas las primitivas liberar y copiar:
} 6 void elemento_liberar(Elemento *pe);
x Elemento *elemento_copiar(const Elemento *pe);
if (ps->top == PILA_MAX-1) { 5
return TRUE; 4 x • Primitivas (prototipos en pila.h)
} Pila *pila_crear(); 7
return FALSE; 3
x void pila_liberar(Pila *ps); 6
}
2 boolean pila_vacia(const Pila *ps); x
x 5
1
boolean pila_llena(const Pila *ps);
status pila_push(Pila *ps, const Elemento *pe); 4 x
Nota: 7 0 x
Elemento *pila_pop(Pila *ps); 3
Llamaremos a pila_llena antes de hacer push, comprobando si x
top datos x
la pila tiene o no capacidad. Si la pila está llena, no llamaremos a • Estructura de datos (en pila.c) 2
x
push. struct _Pila { 1
Por eso, si ps es NULL, aquí detectamos el error y devolvemos Elemento *datos[PILA_MAX]; x
ps int top; 4 0
TRUE indicando que la pila “está” llena, con el fin de que luego
no se haga push. }; top datos
Implementación en C de Pila 22
Implementación en C de Pila 23
• Implementación con top de tipo entero • Implementación con top de tipo entero
status pila_push(Pila *ps, const Elemento *pe) { status pila_push(Pila *ps, const Elemento *pe) {
Elemento *aux = NULL; Elemento *aux = NULL;
if (ps == NULL || pe == NULL || pila_llena(ps) == TRUE) { if (ps == NULL || pe == NULL || pila_llena(ps) == TRUE) {
return ERR; aux return ERR; aux
} }
• Implementación con top de tipo entero • Implementación con top de tipo entero
• Asumimos la existencia del TAD Elemento que, entre otras, Elemento *pila_pop(Pila *ps){
Elemento *pe = NULL; pe
tiene asociadas las primitivas liberar y copiar:
void elemento_liberar(Elemento *pe); if (ps == NULL || pila_vacia(ps) == TRUE) {
return NULL;
Elemento *elemento_copiar(const Elemento *pe);
}
7 pop 7
}; top datos
ps ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 26
Contenidos 27
}
return NULL;
7 pop 7 • Implementación en C de Pila
6 6 • Implementación con top de tipo entero
// Recuperamos el dato del top
5 5
pe = ps->datos[ps->top];
• Ejemplos de aplicación de Pila
4 e 4 e
// Ponemos el Elemento* a NULL
ps->datos [ps->top] = NULL; 3 3
• Balanceo de paréntesis
x x
// Actualizamos el top
2 2 • Evaluación de expresiones posfijo
x x
ps->top--; 1 1 • Conversión entre notaciones infijo, posfijo y prefijo
4 0 x 3 0 x
return pe;
} top datos x top datos x • Anexo
Nota: el elemento cuyo puntero
se devuelve ha de liberarse fuera, • Implementación con top de tipo puntero
tras la llamada a pop ps ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Balanceo de paréntesis 28
Balanceo de paréntesis 29
Balanceo de paréntesis 30
Balanceo de paréntesis 31
Balanceo de paréntesis 34
Balanceo de paréntesis 35
mientras (it=leerSimbolo(S)) ≠ FIN: // leer siguiente símbolo de S mientras (it=leerSimbolo(S)) ≠ FIN: // leer siguiente símbolo de S
si esSimboloApertura(it) // si es (, [ o { si esSimboloApertura(it) // si es (, [ o {
pila_push(p,it) pila_push(p,it)
si no, si esSimboloCierre(it) si no, si esSimboloCierre(it)
e = pila_pop(p) e = pila_pop(p)
si e=NULL O (it=')' Y e≠'(') si e=NULL O sonParentesisPareja(it,e)=FALSE
O (it=']' Y e≠'[') pila_liberar(p)
O (it='}' Y e≠'{') devolver FALSE
pila_liberar(p)
devolver FALSE si pila_vacia(p) = FALSE
pila_liberar(p)
si pila_vacia(p) = FALSE devolver FALSE
pila_liberar(p) pila_liberar(p)
devolver FALSE devolver TRUE
pila_liberar(p) }
devolver TRUE
}
Balanceo de paréntesis 38
Contenidos 39
• Ejemplos
• Notación infijo • Ejemplo: 2 3 + 3 1 + + ;
• Los operadores se indican entre operandos: A+B
• La habitual 1
5 9
• Los operadores se indican después de los operandos: AB+
• La más “práctica” para un ordenador • Ejemplo: 1 2 * 4 2 / 3 4 + 5 * - + ;
• Notación prefijo
• Los operadores se indican antes de los operandos: +AB
• Ejemplo:
• En infijo: 2 - 3 * (4 + 1)
• En posfijo: 2 3 4 1 + * -
• En prefijo: - 2 * 3 + 4 1
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
r = pila_pop(p)
A B * C - ; si pila_vacia(p)=FALSE // si la pila no queda vacía, incorrecto
pila_liberar(p)
devolver ERROR
Contenidos 46
Conversión de expresiones: infijo-posfijo 47
• Infijo Posfijo
• El TAD Pila
• Conversión de A + B * C
• Estructura de datos y primitivas de Pila • A +(B * C)=> AB+C*
• Implementación en C de Pila • A + B * C => ABC*+
• Idea inicial
A + B * C ; => ABC*+
• Otro ejemplo
Símbolo Traducción parcial Pila de OPERADORES A * B + C / E ; => AB*CE/+
A A Símbolo Traducción parcial Pila de OPERADORES
+ A + A A
B AB + * A *
* AB + * B AB *
C ABC + * + AB * +
; ABC*+ C ABC * +
/ ABC * + /
• Posible algoritmo E ABCE * + /
; ABCE/+* MAL
1. Si el símbolo actual it es operando: “imprimir”
(añadir it a cadena de traducción parcial)
• Ajustes al algoritmo
2. Si it es operador: pila_push(pila, it)
• Los operadores de mayor precedencia salen antes de pila
3. Al final: vaciar pila e imprimiendo elementos en cadena
• A igual precedencia, sale antes el que se leyó antes
traducción en el orden en que se van extrayendo
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
• Algoritmo
• Teniendo en cuenta precedencia de operadores 1. Si it es operando, añadir a la expresión
A * B + C / E ; => AB*CE/+
2. Si es operador:
Símbolo Traducción parcial Pila de OPERADORES
A A
mientras prec (operador) ≤ prec (tope(pila))
* A * extraer elemento de la pila y añadir a la expresión
B AB * meter operador leído en la pila
+ AB* +
C AB*C +
3. Si es fin de cadena:
/ AB*C + / mientras pila no vacía:
E AB*CE + / extraer elemento de la pila y añadirlo a la expresión
; AB*CE/+
• Con paréntesis…
• ¡Ojo! A diferencia de la evaluación, el algoritmo de A * B / (C + D) * (E – F);
conversión no detecta errores sintácticos
• Clave: tratar las expresiones entre paréntesis como
• A+B* AB*+
expresiones en si misma se traducen antes de seguir la
• ABC* ABC*
traducción general
• Función de precedencia • Ejemplo: A * B / [CD+] * [EF-] => AB*CD+/EF-*
int prec(char op)
switch(op) {
• En la práctica:
case '+': case '-': return 1; • ‘(‘ se introduce en la pila
case '*': case '/': return 2;
case '^': return 3; • cuando se encuentra ‘)’ se sacan todos los operadores hasta ‘(‘
}
return 0; // Error • ¿Hay que tener en cuenta el balanceado de paréntesis?
} • El algoritmo de conversión lo tendrá en cuenta
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Conversión de expresiones: infijo-posfijo 56
Conversión de expresiones: infijo-posfijo 57
• Infijo
prefijo • Evaluar la siguiente expresión sufijo
2 1 / 4 2 * + 6 5 – 8 2 / + + ;
Algoritmo: infijo sufijo prefijo
• Convertir la siguiente expresión infijo en sufijo
A + B / C – D * F ;
• Ejemplos:
• Convertir la siguiente expresión infijo en sufijo
A+B–C; (A+B)*(C-D); (A + B) / C * (D – E) + F ;
• Convertir la siguiente expresión sufijo en infijo
A B C / + D F * - ;
• Convertir la siguiente expresión sufijo en prefijo
A B C / + D F * - ;
• Evaluar la siguiente expresión prefijo
/ / 6 5 – 9 3 ;
Contenidos 62
Implementación en C de Pila 63
• El TAD Pila
• Estructura de datos y primitivas de Pila • Implementación con top de tipo puntero
• Asumimos la existencia del TAD Elemento
• Implementación en C de Pila 7
• EdD de Pila mediante un array
• Implementación con top de tipo entero 6
// En pila.h x
5
• Ejemplos de aplicación de Pila typedef struct _Pila Pila;
4 x
• Balanceo de paréntesis // En pila.c 3
#define PILA_MAX 8 x
• Evaluación de expresiones posfijo struct _Pila { 2
x
Elemento *datos[PILA_MAX];
• Conversión entre notaciones infijo, posfijo y prefijo 1
Elemento **top; x
0
};
• Anexo top datos
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
• Asumimos la existencia del TAD Elemento que, entre otras, • Asumimos la existencia del TAD Elemento que, entre otras,
tiene asociadas las primitivas liberar y copiar: tiene asociadas las primitivas liberar y copiar:
void elemento_liberar(Elemento *pe); void elemento_liberar(Elemento *pe);
Elemento *elemento_copiar(const Elemento *pe); Elemento *elemento_copiar(const Elemento *pe);
Implementación en C de Pila 66
Implementación en C de Pila 67
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
Existe: void elemento_liberar(Elemento *pe);
Pila *pila_crear() {
vacía 7
Pila *ps = NULL;
void pila_liberar(Pila *ps) { 6
int i; 7
6 if (ps != NULL) { 5
ps = (Pila *) malloc(sizeof(Pila));
while (ps->top >= ps->datos) {
if (ps == NULL) { 5 4 x
elemento_liberar(ps->top);
return NULL;
ps->top--; 3
} 4 x
}
3 2
free(ps);
for (int i=0; i<PILA_MAX; i++) { // Bucle opcional x
// ps = NULL; se hace fuera, 1
ps->datos[i] = NULL; 2 // tras llamar a pila_liberar
} } 0 x
1
}
ps->top = NULL; 0 top datos x
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
Existe: void elemento_liberar(Elemento *pe); Existe: void elemento_liberar(Elemento *pe);
7 7
void pila_liberar(Pila *ps) { 6 void pila_liberar(Pila *ps) { 6
ps
ps
Implementación en C de Pila 70
Implementación en C de Pila 71
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
• Asumimos la existencia del TAD Elemento que, entre otras,
tiene asociadas las primitivas liberar y copiar: vacía
void elemento_liberar(Elemento *pe);
Elemento *elemento_copiar(const Elemento *pe); boolean pila_vacia(const Pila *ps) { 7
if (ps == NULL) {
6
• Primitivas (prototipos en pila.h) return TRUE;
7 } 5
Pila *pila_crear();
void pila_liberar(Pila *ps); 6 4
boolean pila_vacia(const Pila *ps); x if (ps->top == NULL) {
5 return TRUE; 3
boolean pila_llena(const Pila *ps);
x }
status pila_push(Pila *ps, const Elemento *pe); 4 2
return FALSE;
Elemento *pila_pop(Pila *ps); }
3 x 1
• Estructura de datos (en pila.c) 2 0
x
struct _Pila { 1 top datos
Elemento *datos[PILA_MAX]; x
0
Elemento **top;
}; top datos
ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 72
Implementación en C de Pila 73
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
• Asumimos la existencia del TAD Elemento que, entre otras,
llena x
tiene asociadas las primitivas liberar y copiar:
void elemento_liberar(Elemento *pe);
boolean pila_llena(const Pila *ps) {
7 Elemento *elemento_copiar(const Elemento *pe);
if (ps == NULL) { x
return TRUE; 6
} x • Primitivas (prototipos en pila.h)
5 7
Pila *pila_crear();
// if (ps->top == ps->datos + PILA_MAX - 1) 4 x void pila_liberar(Pila *ps); 6
if (ps->top == &(ps->datos[PILA_MAX-1])) { boolean pila_vacia(const Pila *ps); x
3 5
return TRUE; x boolean pila_llena(const Pila *ps);
} 2 status pila_push(Pila *ps, const Elemento *pe); 4 x
return FALSE; x Elemento *pila_pop(Pila *ps);
3
} 1 x
0 x • Estructura de datos (en pila.c) 2
x
struct _Pila { 1
top datos x Elemento *datos[PILA_MAX]; x
0
Elemento **top;
}; top datos
ps
Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
Escuela Politécnica Superior Escuela Politécnica Superior
Universidad Autónoma de Madrid Universidad Autónoma de Madrid
Implementación en C de Pila 74
Implementación en C de Pila 75
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
status pila_push(Pila *ps, const Elemento *pe){ status pila_push(Pila *ps, const Elemento *pe){
Elemento *aux = NULL; Elemento *aux = NULL;
if (ps == NULL || pe == NULL || pila_llena(ps) == TRUE) { if (ps == NULL || pe == NULL || pila_llena(ps) == TRUE) {
return ERR; aux return ERR; aux
} }
7 push 7 7 push 7
aux = elemento_copiar(pe); aux = elemento_copiar(pe);
if (aux == NULL) { 6 6 if (aux == NULL) { 6 6
return ERR; return ERR;
5 5 e 5 5 e
} }
// Actualizamos el top
4 x 4 x // Actualizamos el top
4 x 4 x
if (ps->top == NULL) { 3 3 if (ps->top == NULL) { 3 3
// ps->top = ps->datos x x // ps->top = ps->datos x x
ps->top = &(ps->datos[0]); 2 2 ps->top = &(ps->datos[0]); 2 2
} x x } x x
else { 1 1 else { 1 1
ps->top++;
0 x 0 x ps->top++;
0 x 0 x
} }
e top datos x e top datos x e top datos x e top datos x
// Guardamos el dato en el top // Guardamos el
*(ps->top) = aux; // dato en el top
*(ps->top) = aux;
return OK; Programación II – Tema 2: Pilas Programación II – Tema 2: Pilas
} Escuela Politécnica Superior return OK; Escuela Politécnica Superior
pe ps Autónoma de Madrid
Universidad pe ps }
pe ps Autónoma de Madrid
Universidad pe ps
Implementación en C de Pila 76
Implementación en C de Pila 77
• Implementación con top de tipo puntero • Implementación con top de tipo puntero
Elemento *pila_pop(const Pila *ps){
• Asumimos la existencia del TAD Elemento que, entre otras, Elemento *pe = NULL; pe
tiene asociadas las primitivas liberar y copiar: if (ps == NULL || pila_vacia(ps) == TRUE) {
void elemento_liberar(Elemento *pe); return NULL;
Elemento *elemento_copiar(const Elemento *pe); } 7 pop 7
Implementación en C de Pila 78
6 6
// Recuperamos el dato del top
pe = *(ps->top); 5
5