Open In App

Python Program For In-Place Merge Two Linked Lists Without Changing Links Of First List

Last Updated : 18 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given two sorted singly linked lists having n and m elements each, merge them using constant space. First, n smallest elements in both the lists should become part of the first list and the rest elements should be part of the second list. Sorted order should be maintained. We are not allowed to change pointers of the first linked list.

Example:

Input:
First List: 2->4->7->8->10
Second List: 1->3->12

Output: 
First List: 1->2->3->4->7
Second List: 8->10->12

We strongly recommend you to minimize your browser and try this yourself first.
The problem becomes very simple if we’re allowed to change pointers of the first linked list. If we are allowed to change links, we can simply do something like a merge of the merge-sort algorithm. We assign the first n smallest elements to the first linked list where n is the number of elements in the first linked list and the rest to the second linked list. We can achieve this in O(m + n) time and O(1) space, but this solution violates the requirement that we can’t change links of the first list.

The problem becomes a little tricky as we’re not allowed to change pointers in the first linked list. The idea is something similar to this post but as we are given a singly linked list, we can’t proceed backward with the last element of LL2. 

The idea is for each element of LL1, we compare it with the first element of LL2. If LL1 has a greater element than the first element of LL2, then we swap the two elements involved. To keep LL2 sorted, we need to place the first element of LL2 at its correct position. We can find a mismatch by traversing LL2 once and correcting the pointers. 

Below is the implementation of this idea. 

Python3




# Python3 program to merge two sorted linked 
# lists without using any extra space and 
# without changing links of first list
  
# Structure for a linked list node 
class Node:    
    def __init__(self):        
        self.data = 0
        self.next = None
      
# Given a reference (pointer to pointer) to 
# the head of a list and an int, push a new
# node on the front of the list. 
def push(head_ref, new_data):
  
    # Allocate node 
    new_node = Node()
   
    # Put in the data  
    new_node.data  = new_data
   
    # Link the old list off the 
    # new node 
    new_node.next = (head_ref)
   
    # Move the head to point to 
    # the new node 
    (head_ref) = new_node
    return head_ref
  
# Function to merge two sorted linked lists
# LL1 and LL2 without using any extra space.
def mergeLists(a, b):
  
    # Run till either one of a 
    # or b runs out
    while (a and b):
  
        # For each element of LL1, compare
        # it with first element of LL2.
        if (a.data > b.data):
      
            # Swap the two elements involved
            # if LL1 has a greater element
            a.data, b.data = b.data, a.data
   
            temp = b
   
            # To keep LL2 sorted, place first
            # element of LL2 at its correct place
            if (b.next and b.data > b.next.data):
                b = b.next
                ptr = b
                prev = None
                  
                # Find mismatch by traversing the
                # second linked list once
                while (ptr and ptr.data < temp.data):
                    prev = ptr
                    ptr = ptr.next
          
                # Correct the pointers
                prev.next = temp
                temp.next = ptr
          
        # Move LL1 pointer to next element
        a = a.next
      
# Function to print the linked link
def printList(head):
    while (head):
        print(head.data, end = '->')
        head = head.next
      
    print('NULL')
      
# Driver code
if __name__=='__main__':    
    a = None
    a = push(a, 10)
    a = push(a, 8)
    a = push(a, 7)
    a = push(a, 4)
    a = push(a, 2)
   
    b = None
    b = push(b, 12)
    b = push(b, 3)
    b = push(b, 1)
   
    mergeLists(a, b)
   
    print("First List: "
           end = '')
    printList(a)
   
    print("Second List: "
           end = '')
    printList(b)
# This code is contributed by rutvik_56


Output : 

First List: 1->2->3->4->7->NULL
Second List: 8->10->12->NULL

Time Complexity : O(mn)

Auxiliary Space: O(1)

Please refer complete article on In-place Merge two linked lists without changing links of first list for more details!



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads