Bird
0
0
DSA Cprogramming

Reverse a Doubly Linked List in DSA C

Choose your learning style9 modes available
Mental Model
We flip the direction of each link between nodes so the list goes backward instead of forward.
Analogy: Imagine a train where each carriage can connect to the one before and after. Reversing the train means swapping these connections so the last carriage becomes the first.
null ← 1 ↔ 2 ↔ 3 -> null
↑ head
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3, reverse the list
Goal: Change the list so it reads 3 ↔ 2 ↔ 1 instead of 1 ↔ 2 ↔ 3
Step 1: Start at head (node 1), swap its prev and next pointers
null ← 1 [prev=null, next=2] -> null
After swap: null ← 1 [prev=2, next=null] -> null
Head at 1
Why: Swapping pointers reverses the direction of links for this node
Step 2: Move to next node using old next pointer (node 2), swap its prev and next
null ← 1 ← 2 -> 3 -> null
After swap: null ← 1 ← 2 [prev=3, next=1] -> null
Head at 1
Why: Continue reversing links for each node
Step 3: Move to next node (node 3), swap its prev and next
null ← 1 ← 2 ← 3 -> null
After swap: null ← 1 ← 2 ← 3 [prev=null, next=2] -> null
Head at 1
Why: Last node's pointers swapped, reversing its links
Step 4: Update head to last processed node (node 3)
null ← 3 ↔ 2 ↔ 1 -> null
↑ head
Why: New head is the old tail after reversal
Result:
null ← 3 ↔ 2 ↔ 1 -> null
Head points to node 3
Annotated Code
DSA C
#include <stdio.h>
#include <stdlib.h>

// Node structure for doubly linked list
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;

// Create a new node
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->prev = NULL;
    newNode->next = NULL;
    return newNode;
}

// Append node at end
void append(Node** head_ref, int data) {
    Node* newNode = createNode(data);
    if (*head_ref == NULL) {
        *head_ref = newNode;
        return;
    }
    Node* temp = *head_ref;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
}

// Reverse the doubly linked list
void reverse(Node** head_ref) {
    Node* curr = *head_ref;
    Node* temp = NULL;

    while (curr != NULL) {
        // Swap prev and next pointers
        temp = curr->prev;
        curr->prev = curr->next;
        curr->next = temp;

        // Move curr to next node in original list (which is prev now)
        curr = curr->prev;
    }

    // After loop, temp points to previous node, update head
    if (temp != NULL) {
        *head_ref = temp->prev;
    }
}

// Print list from head to tail
void printList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d", temp->data);
        if (temp->next != NULL) {
            printf(" ↔ ");
        }
        temp = temp->next;
    }
    printf(" -> null\n");
}

int main() {
    Node* head = NULL;
    append(&head, 1);
    append(&head, 2);
    append(&head, 3);

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

    reverse(&head);

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

    return 0;
}
while (curr != NULL) {
Traverse each node to reverse pointers
temp = curr->prev;
Store original prev pointer before swap
curr->prev = curr->next;
Swap prev and next pointers to reverse link
curr->next = temp;
Complete pointer swap for current node
curr = curr->prev;
Move to next node in original order (prev after swap)
if (temp != NULL) { *head_ref = temp->prev; }
Update head to new first node after reversal
OutputSuccess
Original list: 1 ↔ 2 ↔ 3 -> null Reversed list: 3 ↔ 2 ↔ 1 -> null
Complexity Analysis
Time: O(n) because we visit each of the n nodes once to swap pointers
Space: O(1) because we only use a few extra variables, no extra list
vs Alternative: Compared to creating a new reversed list (O(n) time and space), this reverses in place saving memory
Edge Cases
Empty list (head is NULL)
Function does nothing and head remains NULL
DSA C
while (curr != NULL) {
Single node list
Pointers swap but list remains same, head unchanged
DSA C
while (curr != NULL) {
When to Use This Pattern
When you see a problem asking to reverse a doubly linked list, reach for pointer swapping because each node has two links that must be flipped.
Common Mistakes
Mistake: Not updating the head pointer after reversal
Fix: Set head to the last processed node's prev pointer after loop ends
Mistake: Moving to curr->next instead of curr->prev after swapping
Fix: Move to curr->prev because pointers are swapped
Summary
Reverses the direction of a doubly linked list by swapping each node's prev and next pointers.
Use when you need to reverse the order of elements in a doubly linked list efficiently.
The key insight is that swapping prev and next pointers at each node reverses the entire list.