Reverse a Singly Linked List Recursive in DSA C - Time & Space Complexity
We want to understand how the time needed to reverse a linked list grows as the list gets longer.
Specifically, how many steps does the recursive method take as the list size increases?
Analyze the time complexity of the following code snippet.
struct Node {
int data;
struct Node* next;
};
struct Node* reverseRecursive(struct Node* head) {
if (head == NULL || head->next == NULL) return head;
struct Node* rest = reverseRecursive(head->next);
head->next->next = head;
head->next = NULL;
return rest;
}
This code reverses a singly linked list by calling itself on the next node until it reaches the end, then rewires the links backward.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive call on the next node of the list.
- How many times: Once for each node in the list, so n times for a list of size n.
Each node causes one recursive call, so the number of steps grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 recursive calls and rewiring steps |
| 100 | About 100 recursive calls and rewiring steps |
| 1000 | About 1000 recursive calls and rewiring steps |
Pattern observation: The work grows linearly as the list size increases.
Time Complexity: O(n)
This means the time to reverse the list grows in direct proportion to the number of nodes.
[X] Wrong: "Recursive reversal is faster than iterative reversal because recursion is magical."
[OK] Correct: Both recursive and iterative methods visit each node once, so they take similar time. Recursion adds extra overhead from function calls but does not reduce the total steps.
Understanding recursive reversal helps you think about how recursion works on linked structures, a key skill for many coding problems.
"What if we changed the recursion to an iterative loop? How would the time complexity change?"
Practice
Solution
Step 1: Understand recursion on linked list
Recursion reverses the list from the second node onward first.Step 2: Fix the first node's next pointer
After recursion returns, the first node's next pointer is set to null and the previous node points back to it.Final Answer:
Reverse the rest of the list and then fix the first node's next pointer -> Option BQuick Check:
Recursive reversal = Reverse rest + fix first [OK]
- Trying to swap node data instead of pointers
- Not setting the first node's next to null
- Confusing iterative and recursive methods
Solution
Step 1: Identify base cases for recursion
Base case must handle empty list and single node list to stop recursion.Step 2: Choose correct condition
Condition 'head == NULL || head->next == NULL' covers both empty and single node cases.Final Answer:
if (head == NULL || head->next == NULL) return head; -> Option CQuick Check:
Base case = empty or single node [OK]
- Returning NULL for single node list
- Not handling empty list as base case
- Incorrectly modifying head in base case
Solution
Step 1: Trace recursive reversal
Recursion reverses from last node back: 3 becomes new head, 2 points to 1, 1 points to NULL.Step 2: Confirm final list order
Final reversed list is 3 -> 2 -> 1 -> NULL.Final Answer:
3 -> 2 -> 1 -> NULL -> Option DQuick Check:
Reverse(1->2->3) = 3->2->1 [OK]
- Assuming original order remains
- Mixing node values instead of pointers
- Forgetting to set last node's next to NULL
Node* reverse(Node* head) {
if (head == NULL || head->next == NULL) return head;
Node* rest = reverse(head->next);
head->next->next = head;
head->next = head;
return rest;
}Solution
Step 1: Analyze pointer assignments
head->next->next = head correctly points next node back to current node.Step 2: Identify incorrect pointer reset
head->next = head wrongly points current node's next to itself, causing a cycle instead of NULL.Final Answer:
head->next is set to head instead of NULL causing a cycle -> Option AQuick Check:
head->next must be NULL, not head [OK]
- Setting head->next to head causing infinite loop
- Forgetting to return the new head
- Not handling base case properly
Node* reverse(Node* head) {
if (!head || !head->next) return head;
Node* rest = reverse(head->next);
head->next->next = head;
head->next = NULL;
return rest;
}
void printList(Node* head) {
while (head) {
printf("%d -> ", head->data);
head = head->next;
}
printf("NULL\n");
}
int main() {
// List creation omitted for brevity
Node* reversed = reverse(head);
printList(reversed);
}Solution
Step 1: Trace recursive reversal on list 10->20->30->40
Recursion reverses from last node: 40 becomes new head, pointers reversed stepwise.Step 2: Confirm print output
Print function outputs nodes in order: 40 -> 30 -> 20 -> 10 -> NULL.Final Answer:
40 -> 30 -> 20 -> 10 -> NULL -> Option AQuick Check:
Reverse(10->20->30->40) = 40->30->20->10 [OK]
- Assuming original order remains after reverse
- Forgetting to set last node's next to NULL
- Confusing print output with input list
Ready to prove it?
Pass the test and this pattern moves unknown
