Lista doblemente enlazada en C: ejercicio resuelto con inserción y recorrido

Lista doblemente enlazada en C: ejercicio resuelto

Si buscas lista doblemente enlazada en C ejercicio resuelto, este ejemplo te enseña exactamente lo que suele pedirse en prácticas, entrevistas y exámenes: insertar nodos, recorrer en ambos sentidos y liberar memoria correctamente.

Enunciado

Implementa una lista doblemente enlazada con nodos que incluyan:

  • valor
  • puntero siguiente
  • puntero anterior

Crea funciones para:

  • insertar al final,
  • recorrer hacia adelante,
  • recorrer hacia atras,
  • liberar toda la lista.

Solución en C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>
#include <stdlib.h>

typedef struct Nodo {
    int valor;
    struct Nodo *siguiente;
    struct Nodo *anterior;
} Nodo;

Nodo *insertar_final(Nodo *cabeza, int valor) {
    Nodo *nuevo = (Nodo *)malloc(sizeof(Nodo));
    if (nuevo == NULL) {
        fprintf(stderr, "Error al reservar memoria.\n");
        return cabeza;
    }

    nuevo->valor = valor;
    nuevo->siguiente = NULL;
    nuevo->anterior = NULL;

    if (cabeza == NULL) {
        return nuevo;
    }

    Nodo *actual = cabeza;
    while (actual->siguiente != NULL) {
        actual = actual->siguiente;
    }

    actual->siguiente = nuevo;
    nuevo->anterior = actual;
    return cabeza;
}

Nodo *obtener_ultimo(Nodo *cabeza) {
    if (cabeza == NULL) {
        return NULL;
    }

    while (cabeza->siguiente != NULL) {
        cabeza = cabeza->siguiente;
    }

    return cabeza;
}

void recorrer_adelante(Nodo *cabeza) {
    printf("Recorrido hacia adelante:\n");
    while (cabeza != NULL) {
        printf("%d ", cabeza->valor);
        cabeza = cabeza->siguiente;
    }
    printf("\n");
}

void recorrer_atras(Nodo *cola) {
    printf("Recorrido hacia atras:\n");
    while (cola != NULL) {
        printf("%d ", cola->valor);
        cola = cola->anterior;
    }
    printf("\n");
}

void liberar_lista(Nodo *cabeza) {
    while (cabeza != NULL) {
        Nodo *tmp = cabeza;
        cabeza = cabeza->siguiente;
        free(tmp);
    }
}

int main(void) {
    Nodo *lista = NULL;

    lista = insertar_final(lista, 10);
    lista = insertar_final(lista, 20);
    lista = insertar_final(lista, 30);

    recorrer_adelante(lista);
    recorrer_atras(obtener_ultimo(lista));

    liberar_lista(lista);
    return 0;
}

Salida esperada

1
2
3
4
Recorrido hacia adelante:
10 20 30
Recorrido hacia atras:
30 20 10

Complejidad y puntos clave

  • insertar_final: O(n) por recorrer hasta la cola.
  • recorrer_adelante y recorrer_atras: O(n).
  • Espacio extra: O(1) aparte de los nodos.

Errores frecuentes

  • No actualizar anterior al enlazar el nuevo nodo.
  • Perder la referencia de cabeza.
  • No liberar la memoria al final.

Aplicación práctica

Este patrón se usa mucho en problemas actuales de procesamiento de eventos (logs, colas de cambios, historicos) donde necesitas navegar hacia delante y hacia atras en la secuencia.

Siguiente ejercicio recomendado

Práctica guiada y siguiente paso

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Este ejercicio de lista doblemente enlazada en C es avanzado?

Es nivel intermedio-alto. Si ya dominas punteros basicos, es un siguiente paso natural.

¿Dónde hay más ejercicios resueltos de C?

En Programación en C en 100 ejercicios resueltos y en la sección Ejercicios C. También puedes leerlo en Kindle Unlimited: Ver en Amazon.

¿Cómo practicar este tipo de ejercicio para mejorar más rápido?

Empieza con entradas pequeñas, prueba casos límite (vacío, un elemento y capacidad máxima) y luego reescribe la solución sin copiarla.