Bird
Raised Fist0
DSA Cprogramming~15 mins

Merge Two Sorted Linked Lists in DSA C - Deep Dive

Choose your learning style10 modes available
Overview - Merge Two Sorted Linked Lists
What is it?
Merging two sorted linked lists means combining them into one sorted linked list. Each input list is already in order, and the goal is to create a new list that keeps this order. This process involves comparing elements from both lists and linking them in the right sequence. It is a common operation in many algorithms and data handling tasks.
Why it matters
Without merging sorted lists efficiently, programs would waste time sorting data repeatedly or lose the order of information. This would slow down tasks like searching, organizing, or combining data streams. Merging helps keep data organized and speeds up many applications, from databases to real-time systems.
Where it fits
Before learning this, you should understand what linked lists are and how to traverse them. After mastering merging, you can explore sorting algorithms like merge sort, which uses this merging step repeatedly to sort large data sets.
Mental Model
Core Idea
Merging two sorted linked lists means walking through both lists together, always picking the smaller current element to build a new sorted list.
Think of it like...
Imagine two friends lining up in order of height to enter a room. You let them enter one by one, always choosing the shorter person waiting at the front of each line, so the final line inside stays sorted by height.
List1: 1 -> 3 -> 5 -> null
List2: 2 -> 4 -> 6 -> null

Merge process:
Start:
  Compare 1 and 2 -> pick 1
  Compare 3 and 2 -> pick 2
  Compare 3 and 4 -> pick 3
  Compare 5 and 4 -> pick 4
  Compare 5 and 6 -> pick 5
  Leftover 6 -> pick 6

Result:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
Build-Up - 7 Steps
1
FoundationUnderstanding Linked List Structure
šŸ¤”
Concept: Learn what a linked list node is and how nodes connect to form a list.
A linked list is made of nodes. Each node holds a value and a pointer to the next node. The last node points to null, marking the end. For example, a node with value 5 points to the next node with value 10, and so on.
Result
You can represent a list like 5 -> 10 -> 15 -> null using connected nodes.
Understanding nodes and pointers is essential because merging means rearranging these pointers without losing data.
2
FoundationTraversing a Linked List
šŸ¤”
Concept: Learn how to move through a linked list from start to end.
Start at the head node. Visit the current node's value, then move to the next node using the pointer. Repeat until you reach null, which means the list ended.
Result
You can print or access all values in order, like 5, then 10, then 15.
Traversal is the basic operation needed to compare elements during merging.
3
IntermediateComparing Nodes from Two Lists
šŸ¤”Before reading on: do you think you should pick the larger or smaller node value first when merging? Commit to your answer.
Concept: Learn to compare current nodes from both lists to decide which to add next.
At each step, look at the current nodes of both lists. Pick the node with the smaller value to add to the merged list. Move forward in the list from which you picked the node. Repeat until one list is empty.
Result
You build a new list that keeps the order by always choosing the smaller next element.
Knowing to pick the smaller node first keeps the merged list sorted without extra sorting.
4
IntermediateHandling Remaining Nodes After One List Ends
šŸ¤”Before reading on: do you think you need to compare remaining nodes after one list is empty? Commit to your answer.
Concept: Learn what to do when one list finishes before the other during merging.
When one list runs out of nodes, simply link the rest of the other list to the merged list. Since both lists are sorted, the leftover nodes are already in order.
Result
The merged list includes all nodes from both lists, fully sorted.
Recognizing leftover nodes saves unnecessary comparisons and keeps the merge efficient.
5
IntermediateImplementing Merge with a Dummy Node
šŸ¤”
Concept: Use a dummy node to simplify building the merged list without special cases for the head.
Create a dummy node as a starting point. Use a pointer to track the last node in the merged list. As you pick nodes from input lists, link them after the pointer and move the pointer forward. At the end, return dummy's next node as the merged list head.
Result
Code becomes cleaner and easier to manage, avoiding checks for empty merged list head.
Using a dummy node is a common pattern that simplifies pointer management in linked list problems.
6
AdvancedIn-Place Merge Without Extra Memory
šŸ¤”Before reading on: do you think merging requires creating new nodes or can it reuse existing ones? Commit to your answer.
Concept: Merge by rearranging pointers of existing nodes instead of creating new nodes.
Instead of creating new nodes, adjust the next pointers of nodes from the two lists to link them in sorted order. This saves memory and is faster since no new allocation is needed.
Result
The merged list is formed by reusing original nodes, preserving memory and improving performance.
Understanding in-place merging is crucial for efficient real-world applications where memory matters.
7
ExpertRecursive Merge Approach and Its Tradeoffs
šŸ¤”Before reading on: do you think recursion is always better than iteration for merging? Commit to your answer.
Concept: Merge lists using recursion by merging smaller subproblems and combining results.
If either list is empty, return the other. Otherwise, compare heads and recursively merge the rest. The smaller head becomes the merged list head, linking to the recursive merge of the remaining nodes.
Result
Code is elegant and concise but uses extra call stack space proportional to list length.
Knowing recursion tradeoffs helps choose the right approach for constraints like stack size and readability.
Under the Hood
Merging works by moving pointers along both lists simultaneously. At each step, the algorithm compares the current nodes' values and links the smaller one to the merged list. This pointer manipulation continues until all nodes are linked. Internally, no new nodes are created; only the 'next' pointers are changed to reorder nodes.
Why designed this way?
This method was designed to leverage the sorted property of input lists, avoiding full sorting. It minimizes time complexity to linear, O(n), where n is total nodes. Alternatives like concatenating then sorting are slower. Using a dummy node simplifies edge cases, and recursion offers elegant code at the cost of stack space.
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ List1 Head  │     │ List2 Head  │
ā””ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜     ā””ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
      │                   │
      ā–¼                   ā–¼
  [Node1] -> [Node3] -> ...  [Node2] -> [Node4] -> ...
      │                   │
      ā””ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
            │ Compare values
            ā–¼
       [Merged List]
      (Pointers rearranged)
            │
            ā–¼
      Sorted combined list
Myth Busters - 3 Common Misconceptions
Quick: Do you think merging two sorted lists always requires creating new nodes? Commit to yes or no.
Common Belief:You must create new nodes to merge two lists because you need a new combined list.
Tap to reveal reality
Reality:You can merge by just changing pointers of existing nodes without creating new ones.
Why it matters:Creating new nodes wastes memory and time, making the merge less efficient.
Quick: Do you think the merged list can be unsorted if input lists are sorted? Commit to yes or no.
Common Belief:Merging two sorted lists might produce an unsorted list if not careful.
Tap to reveal reality
Reality:If you always pick the smaller current node, the merged list remains sorted.
Why it matters:Incorrect merging breaks order, causing bugs in later processing that expects sorted data.
Quick: Do you think recursion is always better than iteration for merging? Commit to yes or no.
Common Belief:Recursive merging is always better because it is simpler and cleaner.
Tap to reveal reality
Reality:Recursion uses extra stack space and can cause stack overflow on large lists; iteration is safer for big data.
Why it matters:Using recursion blindly can crash programs or waste resources in production.
Expert Zone
1
When merging in-place, careful pointer updates prevent losing access to remaining nodes, a common subtle bug.
2
Using a dummy node avoids special cases for the head node, simplifying code and reducing errors.
3
Recursive merging is elegant but can be replaced by tail recursion optimization in some languages to save stack space.
When NOT to use
Avoid merging linked lists when data is unsorted; instead, sort each list first or use other data structures like balanced trees or arrays. For very large lists, consider external merge sort techniques that handle data on disk.
Production Patterns
Merging sorted linked lists is a core step in merge sort implementations, streaming data merges, and combining sorted event logs. In databases, similar merging happens during index merges and query optimizations.
Connections
Merge Sort Algorithm
Merge sort repeatedly uses merging of sorted lists to sort entire arrays or lists.
Understanding merging linked lists deeply helps grasp how merge sort efficiently sorts data by breaking problems into smaller sorted parts.
Two-Pointer Technique
Merging uses two pointers moving through two lists to compare and pick elements.
Recognizing this pattern helps solve many problems involving sorted arrays or lists by scanning with multiple pointers.
Real-Time Queue Management
Merging sorted lists is like merging sorted event queues in real-time systems to process events in order.
Knowing merging helps design systems that handle multiple ordered streams efficiently, such as network packets or sensor data.
Common Pitfalls
#1Losing track of next nodes when rearranging pointers causes data loss.
Wrong approach:while (list1 != NULL && list2 != NULL) { if (list1->val < list2->val) { merged->next = list1; merged = merged->next; list1 = list1->next; } else { merged->next = list2; merged = merged->next; list2 = list2->next; } // Missing saving next pointers before reassigning }
Correct approach:while (list1 != NULL && list2 != NULL) { if (list1->val < list2->val) { merged->next = list1; list1 = list1->next; merged = merged->next; } else { merged->next = list2; list2 = list2->next; merged = merged->next; } }
Root cause:Not updating the input list pointers before moving merged pointer causes skipping nodes or infinite loops.
#2Not handling the leftover nodes after one list ends.
Wrong approach:while (list1 != NULL && list2 != NULL) { // merging logic } // Forgot to attach remaining nodes return dummy->next;
Correct approach:while (list1 != NULL && list2 != NULL) { // merging logic } if (list1 != NULL) merged->next = list1; else merged->next = list2; return dummy->next;
Root cause:Ignoring leftover nodes leads to incomplete merged lists and lost data.
#3Using recursion without considering stack limits on large lists.
Wrong approach:ListNode* merge(ListNode* l1, ListNode* l2) { if (!l1) return l2; if (!l2) return l1; if (l1->val < l2->val) { l1->next = merge(l1->next, l2); return l1; } else { l2->next = merge(l1, l2->next); return l2; } }
Correct approach:Use iterative merging for large lists to avoid stack overflow.
Root cause:Recursion depth grows with list size, risking crashes on big inputs.
Key Takeaways
Merging two sorted linked lists means picking the smaller current node from either list to build a new sorted list.
Using a dummy node simplifies pointer management and avoids special cases for the merged list head.
You can merge lists in-place by rearranging pointers without creating new nodes, saving memory and time.
Handling leftover nodes after one list ends is essential to include all data in the merged list.
Recursive merging is elegant but can cause stack overflow on large lists; iterative merging is safer for production.

Practice

(1/5)
1. What is the main goal when merging two sorted linked lists?
easy
A. To create a new sorted linked list containing all elements from both lists
B. To reverse both linked lists
C. To find the maximum element in both lists
D. To delete duplicate elements from both lists

Solution

  1. Step 1: Understand the merge operation

    Merging two sorted linked lists means combining their elements into one list that remains sorted.
  2. Step 2: Identify the goal

    The goal is to create a new sorted linked list that contains all elements from both input lists in order.
  3. Final Answer:

    To create a new sorted linked list containing all elements from both lists -> Option A
  4. Quick Check:

    Merge = combine sorted lists [OK]
Hint: Merging means combining sorted lists into one sorted list [OK]
Common Mistakes:
  • Thinking merge reverses lists
  • Confusing merge with finding max element
  • Assuming merge removes duplicates
2. Which of the following is the correct way to declare a node structure for a singly linked list in C?
easy
A. struct Node { int data; struct Node* next; };
B. struct Node { int data; Node* next; };
C. struct Node { int data; struct Node next; };
D. struct Node { int data; struct Node* prev; };

Solution

  1. Step 1: Check struct syntax for linked list node

    In C, a node contains data and a pointer to the next node. The pointer must be declared as 'struct Node* next;'.
  2. Step 2: Identify correct declaration

    struct Node { int data; struct Node* next; }; correctly declares 'struct Node' with 'int data' and 'struct Node* next;'. struct Node { int data; Node* next; }; misses 'struct' keyword before Node*, struct Node { int data; struct Node next; }; incorrectly uses 'struct Node next;' (not a pointer), and struct Node { int data; struct Node* prev; }; uses 'prev' which is for doubly linked lists.
  3. Final Answer:

    struct Node { int data; struct Node* next; }; -> Option A
  4. Quick Check:

    Node struct needs pointer to next node [OK]
Hint: Node pointer must use 'struct Node*' in C [OK]
Common Mistakes:
  • Omitting 'struct' keyword before Node*
  • Using node instead of pointer for next
  • Confusing singly linked list with doubly linked list
3. What will be the output linked list after merging these two sorted linked lists?

List1: 1 -> 3 -> 5 -> NULL
List2: 2 -> 4 -> 6 -> NULL

Assuming the merge function merges correctly.
medium
A. 1 -> 3 -> 5 -> 2 -> 4 -> 6 -> NULL
B. 2 -> 4 -> 6 -> 1 -> 3 -> 5 -> NULL
C. 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL
D. 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> NULL

Solution

  1. Step 1: Compare elements from both lists in order

    Start with heads: 1 (List1) and 2 (List2). 1 < 2, so 1 goes first. Then compare 3 and 2, 2 < 3, so 2 goes next. Continue this way to merge in sorted order.
  2. Step 2: Build merged list step-by-step

    Merged list: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL.
  3. Final Answer:

    1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL -> Option C
  4. Quick Check:

    Merge keeps sorted order [OK]
Hint: Pick smaller node each step to merge sorted lists [OK]
Common Mistakes:
  • Appending one list after the other without sorting
  • Reversing the order accidentally
  • Skipping nodes during merge
4. Consider this buggy merge function snippet in C:
struct Node* merge(struct Node* l1, struct Node* l2) {
    if (!l1) return l2;
    if (!l2) return l1;
    if (l1->data < l2->data) {
        l1->next = merge(l1->next, l2);
        return l1;
    } else {
        l2->next = merge(l1, l2->next);
        return l2;
    }
}

What is the main issue if this function is called with two sorted lists?
medium
A. It reverses the merged list
B. It merges lists correctly without issues
C. It loses nodes when one list is empty
D. It causes infinite recursion when lists have equal elements

Solution

  1. Step 1: Analyze base cases

    If one list is empty (!l1 or !l2), it correctly returns the other list.
  2. Step 2: Analyze recursive case

    If l1->data < l2->data, it sets l1->next to the merge of the rest and returns l1. Otherwise, sets l2->next to merge(l1, l2->next) and returns l2. However, when l1->data == l2->data, the else branch is taken repeatedly without advancing l1, causing infinite recursion.
  3. Final Answer:

    It causes infinite recursion when lists have equal elements -> Option D
  4. Quick Check:

    Equal elements cause infinite recursion due to no advancement in l1 [OK]
Hint: Recursive merge must handle equal elements to avoid infinite recursion [OK]
Common Mistakes:
  • Thinking equal elements cause infinite recursion
  • Believing it loses nodes on empty lists
  • Assuming it reverses the list
5. You have two sorted linked lists:
List1: 1 -> 4 -> 7 -> NULL
List2: 2 -> 4 -> 6 -> 8 -> NULL

Write the merged sorted linked list after merging them and removing duplicate values.
hard
A. 1 -> 4 -> 7 -> 2 -> 4 -> 6 -> 8 -> NULL
B. 1 -> 2 -> 4 -> 6 -> 7 -> 8 -> NULL
C. 1 -> 2 -> 4 -> 4 -> 6 -> 7 -> 8 -> NULL
D. 1 -> 2 -> 6 -> 7 -> 8 -> NULL

Solution

  1. Step 1: Merge lists in sorted order

    Merge elements: 1, 2, 4, 4, 6, 7, 8.
  2. Step 2: Remove duplicate values

    Remove one of the duplicate 4's to get: 1 -> 2 -> 4 -> 6 -> 7 -> 8 -> NULL.
  3. Final Answer:

    1 -> 2 -> 4 -> 6 -> 7 -> 8 -> NULL -> Option B
  4. Quick Check:

    Merge + remove duplicates = sorted unique list [OK]
Hint: Merge then skip duplicates for unique sorted list [OK]
Common Mistakes:
  • Leaving duplicates in merged list
  • Appending lists without sorting
  • Removing unique elements by mistake
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard