Doubly linked list in C: solved exercise with insert and traversal

  3 minutes

If you searched for doubly linked list in C solved exercise, this example covers the exact interview and exam pattern: insert nodes, traverse both directions, and free memory correctly.

Implement a doubly linked list where each node contains:

  • value
  • next pointer
  • prev pointer

Create functions to:

  • append at the end,
  • traverse forward,
  • traverse backward,
  • free the full list.
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int value;
    struct Node *next;
    struct Node *prev;
} Node;

Node *append(Node *head, int value) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode == NULL) {
        fprintf(stderr, "Memory allocation error.\n");
        return head;
    }

    newNode->value = value;
    newNode->next = NULL;
    newNode->prev = NULL;

    if (head == NULL) {
        return newNode;
    }

    Node *current = head;
    while (current->next != NULL) {
        current = current->next;
    }

    current->next = newNode;
    newNode->prev = current;
    return head;
}

Node *getTail(Node *head) {
    if (head == NULL) {
        return NULL;
    }

    while (head->next != NULL) {
        head = head->next;
    }

    return head;
}

void traverseForward(Node *head) {
    printf("Forward traversal:\n");
    while (head != NULL) {
        printf("%d ", head->value);
        head = head->next;
    }
    printf("\n");
}

void traverseBackward(Node *tail) {
    printf("Backward traversal:\n");
    while (tail != NULL) {
        printf("%d ", tail->value);
        tail = tail->prev;
    }
    printf("\n");
}

void freeList(Node *head) {
    while (head != NULL) {
        Node *tmp = head;
        head = head->next;
        free(tmp);
    }
}

int main(void) {
    Node *list = NULL;

    list = append(list, 10);
    list = append(list, 20);
    list = append(list, 30);

    traverseForward(list);
    traverseBackward(getTail(list));

    freeList(list);
    return 0;
}
Forward traversal:
10 20 30
Backward traversal:
30 20 10
  • append: O(n) due to tail search.
  • traverseForward and traverseBackward: O(n).
  • Extra space: O(1) excluding node storage.
  • Forgetting to update prev when linking new nodes.
  • Losing the head reference.
  • Skipping memory cleanup.

This pattern appears in modern event-processing tasks (logs, change streams, history navigation) where two-way traversal is useful.

If you want a complete path with progressive difficulty:

It is intermediate-to-advanced. If you already know basic pointers, this is a strong next step.

At Programming in C in 100 Solved Exercises and in the C Exercises section. Kindle Unlimited option: View on Amazon.

Start with small inputs, run edge cases (empty, one item, max capacity), then rewrite the solution from scratch without copying.