how to find the first node smaller than a given value in a linked list python

Question:

I have a linked list with the node and list method thats:

class Node:
    def __init__(self, value):
        self._value = value 
        self._next = None

class LinkedList():
    def __init__(self):
        self._head = None
    def add(self, node):
        node._next = self._head
        self._head = node
    def insert(self,node1,node2):
        assert node1 != None
        node2._next = node1._next
        node1._next = node2

then inside of the linked list class that finds which node is the first one thats smaller than the given node and inserts it

def find(self,value):
    current = self._head 
    while current != None:
         if current._value < value:
             smaller = current
         if current._next == smaller:
             self.insert(current,value)
         current = current._next

this finds nodes that are smaller but it finds multiple of them and does not insert the new node at the first sight is there a way to fix this

ex.) linked list = 5,4,3,1,0
given: 2

the expected result for this example would be 5,4,3,2,1,0

Asked By: Squilliam

||

Answers:

When you find the smaller node, insert the new value and then break out of the loop.

If you don’t find anything lower, use add() to add the new value to the beginning of the list. The else: block of a loop is executed when the loop ends normally instead of from break.

def find(self, value):
    current = self._head
    while current:
        if current._value < value:
            self.insert(current, value)
            break
    else:
        self.add(value)
Answered By: Barmar

As your insert method needs to get the node after which the insertion should happen, and you seem to want to keep your list sorted, you’ll need to look one node ahead when comparing values.

Make sure to create the Node instance before calling insert.

The name find is quite strange for a method that is supposed to insert a node. I would maybe name it insertsorted.

Here is how I would suggest to implement it:

    def insertsorted(self, value):
        # Check if this should become the very first node
        if not self._head or self._head._value < value:
            self.add(Node(value))
        else:
            current = self._head 
            # Compare with the next node's value
            while current._next and current._next._value >= value:
                 current = current._next
            # Found insertion point
            self.insert(current, Node(value))

Here is how you could test it:

# Demo
lst = LinkedList()
lst.insertsorted(3)
lst.insertsorted(1)
lst.insertsorted(5)
lst.insertsorted(4)
lst.insertsorted(2)

The list will have the nodes in descending order.

Answered By: trincot
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.