简体   繁体   中英

Merge two sorted Linked Lists in ascending order in Python: Issue with Singly Linked List pointer update

# Definition for singly-linked list.
class ListNode:
     def __init__(self, x):
         self.val = x
         self.next = None

a = ListNode(5)
b = ListNode(10)
c = ListNode(20)


e = ListNode(0)
f = ListNode(5)
g = ListNode(21)
h = ListNode(30)


a.next = b
b.next = c

e.next = f
f.next = g
g.next = h

So I have two singly linked lists with heads a and e

I want to merge in ascending order of their values. For now, I want to merge them be iterating through both the linked lists, comparing values UNTIL one of the linked lists reaches None (one of the linked lists are shorter than the other and so one will reach None before the other)

class Solution:
    def mergeTwoLists(self, l1, l2):

        tempNode = ListNode(0)
        returnNode = tempNode

        while (l1.next != None) and (l2.next != None):



            if l1.val < l2.val:

                print("l1.val < l2.val", l1.val, l2.val)
                tempNode.next = l1

                tempNode = tempNode.next
                l1 = l1.next

            elif l1.val == l2.val:

                print("l1.val == l2.val", l1.val, l2.val)

                #If both the values are equal, assign l1's value first
                #then make l2's value follow l1's value using tempNode 

                tempNode.next = l1 
                tempNode = tempNode.next #Because of the previous statement, after execution of this statement, I'm assuming tempNode.val is now l1.val and tempNode.next = l1.next

                #tempNode.next is supposed to be equal to l1.next, instead assign it to l2
                tempNode.next = l2
                tempNode = tempNode.next #Because of the previous statement, after execution of this statement, I'm assuming tempNode.val is now l2.val and tempNode.next = l2.next

                #Increment both l1 and l2
                l1 = l1.next
                l2 = l2.next


            else:
                print("l1.val > l2.val", l1.val, l2.val)
                tempNode.next = l2

                tempNode = tempNode.next
                l2 = l2.next

sol = Solution()
sol.mergeTwoLists(a, e)

So here's what I would ideally like to happen but clearly is NOT happening as you will see when you print the statments!

l1.val = 5 > l2.val = 0

increment or move forward with l2!

l1.val = 5 which is == l2.val == 5

they are both equal, so move l1 to it's next AND l2 to it's next

Now, l1.val should be 10 and l2.val should be 21 , but l1.val is being printed as 5 and l2.val is being printed as 21 and stuck in some infinite loop..

Why does l1.val stay at 5 instead of being updated to 10 and why does it stay in this infinite loop instead of one of them reaching their ends according to my while statement?

Problem is in the following code fragment

tempNode.next = l1 
tempNode = tempNode.next 
tempNode.next = l2
tempNode = tempNode.next
l1 = l1.next
l2 = l2.next

Just change it to the following, your code will work

tempNode.next = l1 
tempNode = tempNode.next
l1 = l1.next 
tempNode.next = l2
tempNode = tempNode.next
l2 = l2.next

Problem with your approach is that when you do tempNode.next = l2 you're modifying the actual ListNode that is pointed by l1 which make you stuck in an infinite loop

You need to assign l1 and l2 's values to tempNode.val instead of assigning l1 and l2 nodes themselves to tempNode 's next node. You also need to add l1 or l2 's remaining values to tempNode if the other list is empty.

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x=None):
        self.val = x
        self.next = None

a = ListNode(5)
b = ListNode(10)
c = ListNode(20)


e = ListNode(0)
f = ListNode(5)
g = ListNode(21)
h = ListNode(30)


a.next = b
b.next = c

e.next = f
f.next = g
g.next = h

class Solution:
    def mergeTwoLists(self, l1, l2):

        returnNode = tempNode = ListNode()

        while l1 or l2:
            if not l1:
                print('l1 is empty; adding value from l2:', l2.val)
                tempNode.val = l2.val
                tempNode.next = ListNode()
                tempNode = tempNode.next
                l2 = l2.next
            elif not l2:
                print('l2 is empty; adding value from l1:', l1.val)
                tempNode.val = l1.val
                tempNode.next = ListNode()
                tempNode = tempNode.next
                l1 = l1.next
            elif l1.val < l2.val:

                print("l1.val < l2.val", l1.val, l2.val)
                tempNode.val = l1.val

                tempNode.next = ListNode()
                tempNode = tempNode.next
                l1 = l1.next

            elif l1.val == l2.val:

                print("l1.val == l2.val", l1.val, l2.val)

                #If both the values are equal, assign l1's value first
                #then make l2's value follow l1's value using tempNode

                tempNode.val = l1.val
                tempNode.next = ListNode() #Because of the previous statement, after execution of this statement, I'm assuming tempNode.val is now l1.val and tempNode.next = l1.next
                tempNode = tempNode.next

                #tempNode.next is supposed to be equal to l1.next, instead assign it to l2
                tempNode.val = l2.val
                tempNode.next = ListNode() #Because of the previous statement, after execution of this statement, I'm assuming tempNode.val is now l2.val and tempNode.next = l2.next
                tempNode = tempNode.next

                #Increment both l1 and l2
                l1 = l1.next
                l2 = l2.next


            else:
                print("l1.val > l2.val", l1.val, l2.val)
                tempNode.val = l2.val

                tempNode.next = ListNode()
                tempNode = tempNode.next
                l2 = l2.next
        return returnNode

sol = Solution()
node = sol.mergeTwoLists(a, e)
while node and node.val is not None:
    print(node.val)
    node = node.next

This outputs:

l1.val > l2.val 5 0
l1.val == l2.val 5 5
l1.val < l2.val 10 21
l1.val < l2.val 20 21
l1 is empty; adding value from l2: 21
l1 is empty; adding value from l2: 30
0
5
5
10
20
21
30

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM