La lista enlazada simple en C y C++
En esta lección vas a construir, recorrer y liberar una lista enlazada simple en C y en C++.
Introducción
Una lista enlazada simple (singly linked list) está formada por nodos (nodes), cada uno con un valor y un puntero al nodo siguiente. A diferencia de un arreglo, los nodos no tienen que estar juntos en memoria, así que se puede añadir un elemento sin mover los demás.
Puntos importantes
- Define las condiciones que siempre deben cumplirse (invariantes) antes de escribir las operaciones.
- Trata los casos de estructura vacía, llena y de fallo al reservar memoria.
- Evalúa a la vez la complejidad y la gestión de memoria de cada operación.
Mira cómo funciona
Añade nodos al principio o al final y haz clic en un nodo para borrarlo. Pulsa Reproducir para seguir los punteros next desde head hasta NULL.
Ejemplos de código C y C++
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int value;
struct Node *next;
} Node;
int main(void) {
Node *head = NULL;
for (int value = 3; value >= 1; --value) {
Node *node = malloc(sizeof *node);
if (!node) return 1;
*node = (Node){value, head};
head = node;
}
while (head) {
Node *next = head->next;
printf("%d ", head->value);
free(head);
head = next;
}
puts("");
return 0;
}
1 2 3
#include <iostream>
#include <memory>
struct Node {
int value;
std::unique_ptr<Node> next;
};
int main() {
std::unique_ptr<Node> head;
for (int value = 3; value >= 1; --value) {
head = std::make_unique<Node>(Node{value, std::move(head)});
}
for (Node *node = head.get(); node; node = node->next.get()) {
std::cout << node->value << ' ';
}
std::cout << '\n';
}
1 2 3
Comparación entre C y C++
En la versión de C, cada nodo se reserva con malloc, y al final el programa tiene que recorrer toda la lista para llamar a free en cada nodo. En la versión de C++, los nodos se enlazan con std::unique_ptr, así que cuando se destruye el primer nodo, toda la cadena que le sigue se libera automáticamente.
Los datos (struct) y las operaciones están separados, y la memoria se reserva y se libera a mano.
Las clases y los contenedores protegen la coherencia de los datos y gestionan sus propios recursos.
Ejercicios de práctica
Ejecuta las dos versiones y después modifica el código para ver la diferencia de seguridad que aporta cada lenguaje.
- Añade pruebas para el estado vacío y para el momento en que se alcanza la capacidad máxima.
- Escribe la liberación de la memoria y comprueba que no haya fugas.
- Compara la complejidad con la del contenedor equivalente de la biblioteca estándar.
Practica con un reto
Usa lo que cubre esta lección para resolver un problema real. Cada reto se ejecuta en el navegador, con pruebas al instante y una revisión de IA.
Todos los retos