Lo último que entra, lo primero que sale
A veces hay que recordar las cosas al revés de como llegaron.
1Por qué
Llevas veintitantas lecciones mirando una pila sin que se llamara así. Cada vez que ejecutabas paso a paso y entrabas en una función, aparecía una caja nueva encima; al terminar, desaparecía la de arriba. Eso es lo que hace el computador con las llamadas, y tiene nombre.
Una pila guarda cosas con una regla única: sale la última que entró. Nada más. Deshacer en un editor, volver atrás en el navegador, comprobar que los paréntesis cierran bien — todo eso es la misma estructura, y en todos los casos lo que hace falta es recordar al revés.
Lo bueno es que ya sabes construirla. Una pila es una lista enlazada donde solo se toca la cabeza: meter es lo que hacías en la lección 17 —poner por delante— y sacar es quitar el de delante. Lo único que se añade es la promesa de no tocar el resto.
Y por eso las dos operaciones cuestan lo mismo con tres elementos que con tres millones: nunca se recorre nada.
Al sacar hay una trampa que ya conoces de la 17: hay que mover la cima antes de devolver el nodo, o queda apuntando a un sitio que ya no es tuyo.
2Míralo andar
Este programa funciona. Léelo, y después ejecútalo sin cambiar nada.
#include <stdio.h>#include <stdlib.h>typedef struct Nodo {int valor;struct Nodo *sig;} Nodo;void apilar(Nodo **cima, int x){Nodo *n = malloc(sizeof(Nodo));n->valor = x;n->sig = *cima;*cima = n;}int desapilar(Nodo **cima){Nodo *n = *cima;int v = n->valor;*cima = n->sig;free(n);return v;}int main(void){Nodo *cima = NULL;apilar(&cima, 1);apilar(&cima, 2);apilar(&cima, 3);printf("%d %d\n", desapilar(&cima), desapilar(&cima));while (cima != NULL){Nodo *s = cima->sig;free(cima);cima = s;}return 0;}
- línea 11
Es exactamente el «añadir por delante» de la lección 17. Una pila no necesita nada más para meter. - línea 20
Mover la cima ANTES de soltar el nodo. Al revés, la cima apuntaría a un sitio ya devuelto. - línea 31
Entraron 1, 2 y 3, y salen 3 y 2. La última en entrar es la primera en salir.
3Ahora tú
A desapilar le falta mover la cima, así que la pila se queda mirando lo que ya devolvió. Escribe esa línea, para que salga: 3 2
#include <stdio.h>#include <stdlib.h>typedef struct Nodo {int valor;struct Nodo *sig;} Nodo;void apilar(Nodo **cima, int x){Nodo *n = malloc(sizeof(Nodo));n->valor = x;n->sig = *cima;*cima = n;}int desapilar(Nodo **cima){Nodo *n = *cima;int v = n->valor;free(n);return v;}int main(void){Nodo *cima = NULL;apilar(&cima, 1);apilar(&cima, 2);apilar(&cima, 3);printf("%d %d\n", desapilar(&cima), desapilar(&cima));while (cima != NULL){Nodo *s = cima->sig;free(cima);cima = s;}return 0;}
↖︎ Tu línea va aquí, antes del free. Después ya sería tarde.
Ejecutar
Lo que dice tu programa
↖︎ Escribe tu parte y dale a Ejecutar
Qué pasó
Aquí te aviso si tu programa hace algo raro.
4Qué guarda tu programa
Memoria
↖︎ Ejecuta el programa para ver qué pasa por dentro