AprenderC
← Todas las lecciones

Una lista que crece

Añadir por delante es lo barato: nada se mueve.

1Por qué

Encadenar tres nodos a mano sirve para verlo, pero nadie programa así. Lo normal es que los datos lleguen de uno en uno —de un archivo, del teclado— y la lista vaya creciendo sola.

Añadir por delante son dos líneas, y ninguna mueve nada: el nodo nuevo apunta a lo que era la cabeza, y la cabeza pasa a ser el nodo nuevo. Da igual que la lista tenga tres elementos o tres millones: cuesta lo mismo.

El orden es lo único que hay que cuidar. Si cambias la cabeza antes de que el nodo nuevo apunte a la vieja, pierdes la lista entera: nadie sabe ya dónde estaba. No hay forma de recuperarla y el programa sigue como si nada.

Hay un efecto secundario que sorprende la primera vez: como cada uno se pone delante, la lista sale al revés del orden en que entraron.

Y al terminar hay que devolver los nodos uno por uno. Aquí aparece la trampa: si liberas un nodo y después le pides su siguiente, estás leyendo un sitio que ya devolviste. Hay que guardarse la dirección del siguiente antes de soltar el actual.

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;
int main(void)
{
Nodo *cabeza = NULL;
for (int i = 1; i <= 3; i++)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = i;
n->sig = cabeza;
cabeza = n;
}
Nodo *p = cabeza;
while (p != NULL)
{
printf("%d ", p->valor);
p = p->sig;
}
printf("\n");
while (cabeza != NULL)
{
Nodo *sig = cabeza->sig;
free(cabeza);
cabeza = sig;
}
return 0;
}

3Ahora tú

Este programa deja cada nodo apuntándose a sí mismo, así que el recorrido no termina nunca. Arregla el orden de las dos líneas para que escriba: 16 9 4 1

#include <stdio.h>
#include <stdlib.h>
typedef struct Nodo {
int valor;
struct Nodo *sig;
} Nodo;
int main(void)
{
Nodo *cabeza = NULL;
for (int i = 1; i <= 4; i++)
{
Nodo *n = malloc(sizeof(Nodo));
n->valor = i * i;
cabeza = n;
n->sig = cabeza;
}
Nodo *p = cabeza;
while (p != NULL)
{
printf("%d ", p->valor);
p = p->sig;
}
printf("\n");
while (cabeza != NULL)
{
Nodo *sig = cabeza->sig;
free(cabeza);
cabeza = sig;
}
return 0;
}

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