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)
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
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()
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)
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)
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
There are several issues in your code:
-
You created
merge
as an instance method, but never useself
. 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 thehead
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 toself.head
-
if (current == None)
is never going to be a true condition, as thewhile
condition requires that bothcurrent
andcurrent2
are notNone
. The same goes forif (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 ofcurrent
orcurrent2
isNone
. Also that code can be simplified with the use of theor
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()
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)