0
0
CHow-ToBeginner · 3 min read

How to Reverse a Linked List in C: Simple Guide and Example

To reverse a linked list in C, you iterate through the list while changing each node's next pointer to point to the previous node. Use three pointers: prev, current, and next to track nodes during reversal.
📐

Syntax

The basic syntax to reverse a singly linked list involves a function that takes the head pointer and returns the new head after reversal. You use three pointers:

  • prev: points to the previous node (initially NULL)
  • current: points to the current node being processed
  • next: temporarily stores the next node to visit

Inside a loop, you update current->next to prev, then move prev and current forward until the list ends.

c
struct Node* reverseList(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* current = head;
    struct Node* next = NULL;
    while (current != NULL) {
        next = current->next;    // Save next node
        current->next = prev;    // Reverse current node's pointer
        prev = current;          // Move prev forward
        current = next;          // Move current forward
    }
    return prev; // New head of reversed list
}
💻

Example

This example creates a simple linked list with nodes containing values 1, 2, and 3. It prints the list before and after reversing it using the reverseList function.

c
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
};

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

void printList(struct Node* head) {
    struct Node* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    struct Node* head = malloc(sizeof(struct Node));
    struct Node* second = malloc(sizeof(struct Node));
    struct Node* third = malloc(sizeof(struct Node));

    head->data = 1;
    head->next = second;
    second->data = 2;
    second->next = third;
    third->data = 3;
    third->next = NULL;

    printf("Original list: ");
    printList(head);

    head = reverseList(head);

    printf("Reversed list: ");
    printList(head);

    free(third);
    free(second);
    free(head);

    return 0;
}
Output
Original list: 1 2 3 Reversed list: 3 2 1
⚠️

Common Pitfalls

Common mistakes when reversing a linked list include:

  • Not updating the next pointer before changing current->next, which causes loss of the rest of the list.
  • Forgetting to return the new head (prev) after reversal.
  • Not handling empty lists or single-node lists properly.

Always save the next node before reversing the pointer to avoid losing access to the list.

c
/* Wrong way: losing the rest of the list */
struct Node* reverseListWrong(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* current = head;
    while (current != NULL) {
        current->next = prev; // This line loses the next node
        prev = current;
        current = current->next; // current->next is now prev, causes loop or crash
    }
    return prev;
}

/* Right way: save next before reversing */
struct Node* reverseListRight(struct Node* head) {
    struct Node* prev = NULL;
    struct Node* current = head;
    struct Node* next = NULL;
    while (current != NULL) {
        next = current->next;    // Save next node
        current->next = prev;    // Reverse pointer
        prev = current;
        current = next;
    }
    return prev;
}
📊

Quick Reference

  • Use three pointers: prev, current, and next.
  • Always save next = current->next before changing current->next.
  • Loop until current is NULL.
  • Return prev as the new head of the reversed list.
  • Handle empty or single-node lists safely.

Key Takeaways

Use three pointers to reverse the linked list safely without losing nodes.
Always save the next node before changing pointers to avoid breaking the list.
Return the new head pointer after reversal to update the list start.
Test with empty and single-node lists to ensure robustness.
Free allocated memory after use to avoid memory leaks.