Merge Two Sorted Lists Python

Question:

I’m trying to solve merge sorted linked list problem.For that i’ve created three method. addlast , print and merge For linked list class created a three objects obj and obj1 (To create two linked list) Using obj3 calling a merge method by passing both linked list head pointer.But here it only print linked list 1 instead of both.

My expected result should be creating both linked list and print the sorted linked list.So what could be the reason the my code isn’t working ?

class node:
def __init__(self,data) :
    self.data = data
    self.next = None

class linkedlist:
  def __init__(self) :
     self.head = None

  def addlast(self,data):
    newnode = node(data)
    if self.head == None:
        self.head = newnode
    else:
        current = self.head
        while(current.next != None):
            current = current.next
        current.next = newnode

  def print(self):
    current = self.head
    while(current):
        print(current.data, "-->",end="")
        current = current.next
    print("NUll")

  def merge(self,obj,obj1):
    current = obj.head
    current2 = obj1.head
    newnode = node(None)        
    while current and current2 != None:
        if (current == None):
            newnode.next = current2
            break
        if (current2 == None):
            newnode.next = current
            break
        if current.data <= current2.data:
            newnode.next = current
            current = current.next
            print(newnode.data)
            newnode = newnode.next
        else:
            newnode.next = current2
            current2 = current2.next
            print(newnode.data)
            newnode = newnode.next

        if current:
            newnode.next = current

        if current2:
            newnode.next = current2
        
    print(newnode.data)

obj = linkedlist()
obj.addlast(10)
obj.addlast(20)
obj.addlast(30)
obj.addlast(40)

obj1 = linkedlist()
obj1.addlast(50)
obj1.addlast(60)
obj1.addlast(70)
obj1.addlast(80)

obj3 = linkedlist()
obj3.merge(obj,obj1)
Asked By: MR. ROBOT

||

Answers:

In the merge function you’re not updating the self.head, instance variable your code is merging the list but you’re not keeping track of the head. Modify your code merge function to point the self.head to new node:

  def merge(self,obj,obj1):
    current = obj.head
    current2 = obj1.head
    newnode = node(None)      
    self.head=newnode  
Answered By: Abhinay Yadav

There are several issues in your code:

  • You created merge as an instance method, but never use self. If the intention is to merge a second list into the current list (self), then you need only one argument, i.e. the "other" list, not two.

  • merge should set the head attribute of the list that gets the merge result, i.e. self.head should be assigned a reference.

  • newnode progresses through the merged list, but your code loses track of what was the first node of that merged list, so you need an extra name so that you can later assign to self.head

  • if (current == None) is never going to be a true condition, as the while condition requires that both current and current2 are not None. The same goes for if (current2 == None): it will never be true.

  • The code to link the only remaining list (the last two if statements) should be put after the loop, not inside it. Only after the loop it is certain that one of current or current2 is None. Also that code can be simplified with the use of the or operator.

  • The reason you only see part of the merged list printed, is that you don’t print the nodes that are appended ("in bulk") in that last operation.

Here is the corrected code:

    def merge(self, obj1):  # Only need one argument, not two
        current = self.head  # Use self
        current2 = obj1.head
        dummy = newnode = node(None)  # keep track of this dummy node      
        while current and current2:
            if current.data <= current2.data:
                newnode.next = current
                current = current.next
            else:
                newnode.next = current2
                current2 = current2.next
            newnode = newnode.next  # This is common to both if/else case
 
        newnode.next = current or current2  # out of the loop
        self.head = dummy.next  # update current list's head reference

The calling code should have near the end:

obj.merge(obj1)
obj.print()
Answered By: trincot

This links the 2 lists Studrec and Aves then sort Studrec pulling the corresponding items from Ave.

def revert(Studrec, Ave):
    Studrec, Ave = map(list, zip(*sorted(zip(Studrec, Ave), key=lambda x: x[0])))
    return Studrec, Ave
Studrec, Ave = revert (Studrec, Ave)
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.