Inserción y eliminación
Modifique la lista
Inserción y eliminación es una lección gratuita de C Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C Academy incluye 4 lecciones en total.
Modificar una lista
La ventaja de las listas enlazadas es que permiten realizar inserciones y eliminaciones de forma económica. En lugar de desplazar elementos como en un array, se reorganizan los punteros.
En esta lección se explica cómo insertar y eliminar nodos en distintas posiciones.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(2);
printf("start: %d\n", head->value);
free(head);
return 0;
}Insertar al principio
Insertar en el head tiene un coste O(1). Cree un nodo nuevo, haga que su next apunte al head actual y, después, actualice el head para que apunte al nodo nuevo.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(2);
struct Node *fresh = make(1);
fresh->next = head;
head = fresh;
printf("%d -> %d\n", head->value, head->next->value);
return 0;
}Por qué pasar un puntero doble
Para cambiar el head desde dentro de una función, debe pasar su dirección: un struct Node **.
De lo contrario, la función solo modifica una copia local y el head de quien la llama permanece sin cambios.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void push(struct Node **head, int v) {
struct Node *n = make(v);
n->next = *head;
*head = n;
}
int main(void) {
struct Node *head = NULL;
push(&head, 5);
push(&head, 4);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Insertar al final
Para añadir un nodo al final, debe recorrer la lista hasta el último nodo y, después, enlazar el nuevo nodo mediante su next.
Si la lista está vacía, el nodo nuevo se convierte en el head.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void append(struct Node **head, int v) {
struct Node *n = make(v);
if (!*head) { *head = n; return; }
struct Node *p = *head;
while (p->next) p = p->next;
p->next = n;
}
int main(void) {
struct Node *head = NULL;
append(&head, 1); append(&head, 2);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Insertar después de un nodo
Para insertar en el centro, busque el nodo después del cual desea insertar y, a continuación, coloque el nodo nuevo entre este y su sucesor actual.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void insert_after(struct Node *node, int v) {
struct Node *n = make(v);
n->next = node->next;
node->next = n;
}
int main(void) {
struct Node *head = make(1);
head->next = make(3);
insert_after(head, 2);
printf("%d %d %d\n", head->value, head->next->value, head->next->next->value);
return 0;
}El orden de las operaciones importa
Al insertar un nodo, establezca siempre el next del nodo nuevo antes de cambiar el next del nodo anterior.
Si lo hace al revés, perderá la referencia al resto de la lista.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *a = make(1), *c = make(3);
a->next = c;
struct Node *b = make(2);
b->next = a->next;
a->next = b;
printf("%d %d %d\n", a->value, b->value, c->value);
return 0;
}Eliminar el primer nodo
Eliminar el head significa guardarlo, avanzar el head hasta head->next y, después, liberar el head antiguo.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void pop(struct Node **head) {
if (!*head) return;
struct Node *old = *head;
*head = old->next;
free(old);
}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
pop(&head);
printf("new head: %d\n", head->value);
free(head);
return 0;
}Eliminar por valor
Para eliminar un nodo con un valor determinado, conserve una referencia al nodo anterior para poder saltarse el objetivo estableciendo prev->next = target->next.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void del(struct Node **head, int v) {
struct Node *cur = *head, *prev = NULL;
while (cur && cur->value != v) { prev = cur; cur = cur->next; }
if (!cur) return;
if (prev) prev->next = cur->next; else *head = cur->next;
free(cur);
}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
head->next->next = make(3);
del(&head, 2);
printf("%d %d\n", head->value, head->next->value);
return 0;
}Gestionar el caso del head
La eliminación tiene un caso especial cuando el objetivo es el head: no existe un nodo anterior, por lo que debe actualizar directamente el puntero head.
El puntero doble permite hacerlo de forma sencilla, como se muestra arriba.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *head = make(1);
head->next = make(2);
struct Node *old = head;
head = head->next;
free(old);
printf("head now %d\n", head->value);
free(head);
return 0;
}Evitar fugas de memoria
Todo nodo que elimine de la lista debe recibir free. Si elimina un nodo sin liberarlo, se filtra la memoria que ocupaba.
Del mismo modo, nunca libere un nodo mientras siga enlazado, ya que crearía un puntero colgante.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
int main(void) {
struct Node *n = make(7);
free(n);
printf("node freed, no leak\n");
return 0;
}Mantener el orden al insertar (opcional)
Insertar manteniendo el orden ordenado es una variante habitual: recorra la lista hasta encontrar la posición en la que encaja el valor y, después, insértelo allí.
#include <stdio.h>
#include <stdlib.h>
struct Node { int value; struct Node *next; };
struct Node *make(int v){struct Node*n=malloc(sizeof*n);n->value=v;n->next=NULL;return n;}
void insert_sorted(struct Node **head, int v) {
struct Node *n = make(v);
if (!*head || (*head)->value >= v) { n->next = *head; *head = n; return; }
struct Node *p = *head;
while (p->next && p->next->value < v) p = p->next;
n->next = p->next; p->next = n;
}
int main(void) {
struct Node *head = NULL;
insert_sorted(&head, 3);
insert_sorted(&head, 1);
insert_sorted(&head, 2);
for (struct Node *p = head; p; p = p->next) printf("%d ", p->value);
printf("\n");
return 0;
}Comprobación rápida
Compruebe su comprensión de la modificación de listas.
Resumen
Ha aprendido a insertar y eliminar nodos:
- Insertar al principio tiene un coste O(1); añadir al final o insertar manteniendo el orden requiere recorrer la lista.
- Utilice un puntero doble cuando el head pueda cambiar.
- Inserte con cuidado: establezca el
nextdel nodo nuevo antes de volver a enlazar. - Conserve una referencia al nodo anterior para eliminar nodos y haga siempre
freede los nodos eliminados.
Aprende C con un tutor de IA — gratis
Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.
- Cursos
- 39
- Lecciones
- 144
Preguntas frecuentes
¿La lección «Inserción y eliminación» es gratis?
Sí — el texto completo de «Inserción y eliminación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C Academy, actualiza a CoddyKit PRO. El curso de C Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Inserción y eliminación»?
Modifique la lista Practicas C Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C Academy?
No se requiere experiencia previa. C Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Inserción y eliminación»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C Academy?
Sí. Cada lección de C Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Listas enlazadas simples
- Inserción y eliminación
- Recorrido y búsqueda
- Listas doblemente enlazadas