Thursday, November 28, 2024
Google search engine
HomeData Modelling & AIC++ Program To Merge Two Sorted Lists (In-Place)

C++ Program To Merge Two Sorted Lists (In-Place)

Given two sorted lists, merge them so as to produce a combined sorted list (without using extra space).
Examples:

Input: head1: 5->7->9
        head2: 4->6->8 
Output: 4->5->6->7->8->9
Explanation: The output list is in sorted order.

Input: head1: 1->3->5->7
        head2: 2->4
Output: 1->2->3->4->5->7
Explanation: The output list is in sorted order.

There are different discussed different solutions in post below. 
Merge two sorted linked lists

Method 1 (Recursive):

Approach: The recursive solution can be formed, given the linked lists are sorted.

  1. Compare the head of both linked lists.
  2. Find the smaller node among the two head nodes. The current element will be the smaller node among two head nodes.
  3. The rest elements of both lists will appear after that.
  4. Now run a recursive function with parameters, the next node of the smaller element, and the other head.
  5. The recursive function will return the next smaller element linked with rest of the sorted element. Now point the next of current element to that, i.e curr_ele->next=recursivefunction()
  6. Handle some corner cases. 
    • If both the heads are NULL return null.
    • If one head is null return the other.

C++




// C program to merge two sorted 
// linked lists in-place.
#include <bits/stdc++.h>
using namespace std;
  
struct Node 
{
    int data;
    struct Node* next;
};
  
// Function to create newNode 
// in a linkedlist
Node* newNode(int key)
{
    struct Node* temp = new Node;
    temp->data = key;
    temp->next = NULL;
    return temp;
}
  
// A utility function to print 
// linked list
void printList(Node* node)
{
    while (node != NULL) 
    {
        printf("%d  ", node->data);
        node = node->next;
    }
}
  
// Merges two given lists in-place. 
// This function mainly compares head 
// nodes and calls mergeUtil()
Node* merge(Node* h1, Node* h2)
{
    if (!h1)
        return h2;
    if (!h2)
        return h1;
  
    // start with the linked list
    // whose head data is the least
    if (h1->data < h2->data) 
    {
        h1->next = merge(h1->next, h2);
        return h1;
    }
    else 
    {
        h2->next = merge(h1, h2->next);
        return h2;
    }
}
  
// Driver code
int main()
{
    Node* head1 = newNode(1);
    head1->next = newNode(3);
    head1->next->next = newNode(5);
  
    // 1->3->5 LinkedList created
    Node* head2 = newNode(0);
    head2->next = newNode(2);
    head2->next->next = newNode(4);
  
    // 0->2->4 LinkedList created
    Node* mergedhead = merge(head1, head2);
  
    printList(mergedhead);
    return 0;
}


Output:  

0 1 2 3 4 5 

Complexity Analysis:

  • Time complexity:O(n). 
    Only one traversal of the linked lists are needed.
  • Auxiliary Space:O(n). 
    If the recursive stack space is taken into consideration.

Method 2 (Iterative):

Approach: This approach is very similar to the above recursive approach.

  1. Traverse the list from start to end.
  2. If the head node of second list lies in between two nodes of the first list, insert it there and make the next node of second list the head. Continue this until there is no node left in both lists, i.e. both the lists are traversed.
  3. If the first list has reached end while traversing, point the next node to the head of second list.

Note: Compare both the lists where the list with a smaller head value is the first list.

C++




// C++ program to merge two sorted 
// linked lists in-place.
#include <bits/stdc++.h>
using namespace std;
  
struct Node 
{
    int data;
    struct Node* next;
};
  
// Function to create newNode in 
// a linkedlist
struct Node* newNode(int key)
{
    struct Node* temp = new Node;
    temp->data = key;
    temp->next = NULL;
    return temp;
}
  
// A utility function to print 
// linked list
void printList(struct Node* node)
{
    while (node != NULL) 
    {
        printf("%d  ", node->data);
        node = node->next;
    }
}
  
// Merges two lists with headers as h1 
// and h2. It assumes that h1's data is 
// smaller than or equal to h2's data.
struct Node* mergeUtil(struct Node* h1,
                       struct Node* h2)
{
    // If only one node in first list
    // simply point its head to second list
    if (!h1->next) 
    {
        h1->next = h2;
        return h1;
    }
  
    // Initialize current and next pointers 
    // of both lists
    struct Node *curr1 = h1, 
                *next1 = h1->next;
    struct Node *curr2 = h2, 
                *next2 = h2->next;
  
    while (next1 && curr2) 
    {
        // if curr2 lies in between curr1 
        // and next1 then do curr1->curr2->next1
        if ((curr2->data) >= (curr1->data) && 
            (curr2->data) <= (next1->data)) 
        {
            next2 = curr2->next;
            curr1->next = curr2;
            curr2->next = next1;
  
            // now let curr1 and curr2 to point
            // to their immediate next pointers
            curr1 = curr2;
            curr2 = next2;
        }
        else 
        {
            // if more nodes in first list
            if (next1->next) 
            {
                next1 = next1->next;
                curr1 = curr1->next;
            }
  
            // else point the last node of 
            // first list to the remaining 
            // nodes of second list
            else 
            {
                next1->next = curr2;
                return h1;
            }
        }
    }
    return h1;
}
  
// Merges two given lists in-place. 
// This function mainly compares head 
// nodes and calls mergeUtil()
struct Node* merge(struct Node* h1,
                   struct Node* h2)
{
    if (!h1)
        return h2;
    if (!h2)
        return h1;
  
    // start with the linked list
    // whose head data is the least
    if (h1->data < h2->data)
        return mergeUtil(h1, h2);
    else
        return mergeUtil(h2, h1);
}
  
// Driver code
int main()
{
    struct Node* head1 = newNode(1);
    head1->next = newNode(3);
    head1->next->next = newNode(5);
  
    // 1->3->5 LinkedList created
    struct Node* head2 = newNode(0);
    head2->next = newNode(2);
    head2->next->next = newNode(4);
  
    // 0->2->4 LinkedList created
    struct Node* mergedhead = merge(head1, head2);
  
    printList(mergedhead);
    return 0;
}


Output:  

0 1 2 3 4 5 

Complexity Analysis:

  • Time complexity:O(n). 
    As only one traversal of the linked lists is needed.
  • Auxiliary Space:O(1). 
    As there is no space required.

Please refer complete article on Merge two sorted lists (in-place) for more details!

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments