class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def printList(self):
temp = self.head
while(temp):
print(temp.data)
temp = temp.next
def push(self, newData):
newNode = Node(newData)
newNode.next = self.head
self.head = newNode
def insertAfter(self, prevNode, newData):
if prevNode is None:
print("The given node must be in the linked list")
return
newNode = Node(newData)
newNode.next = prevNode.next
prevNode.next = newNode
def append(self, newData):
newNode = Node(newData)
if self.head is None:
self.head = newNode
return
last = self.head
while(last.next):
last = last.next
last.next = newNode
def deleteNode(self, key):
temp = self.head
if(temp is not None):
if(temp.data == key):
self.head = temp.next
temp = None
return
while(temp is not None):
if temp.data == key:
break
prev = temp
temp = temp.next
if(temp == None):
return
prev.next = temp.next
temp = None
def __repr__(self):
return 'LinkedList(%s)' % str(self)
def __iter__(self):
current = self.head
while current:
yield current.data
current = current.next
def __str__(self):
return '[%s]' % ', '.join([x for x in self])
if __name__ == '__main__':
list = LinkedList()
while True:
print("1. Add an element")
print("2. Delete an element")
print("3. Push an element")
print("4. Insert after an element")
print("5. Print the list")
menu = int(input("Choose an action: "))
if menu == 1:
data = input("Add an element: ")
list.append(data)
elif menu == 2:
key = input("Add an existing element to delete: ")
list.deleteNode(key)
elif menu == 3:
newData = input("Push an element: ")
list.push(newData)
elif menu == 4:
prevNode = input("Add an element to insert after[Previous Node]: ")
newData = input("Add an element to insert after[New Data]: ")
list.insertAfter(prevNode,newData)
elif menu == 5:
print(list)
else:
print("Wrong input try again. ")
the error is coming from the insertAfter()
when I start passing some values in list.insertAfter(prevNode, newData)
but I couldn't figure out how the error occur.
sample inputs:
[godbless, iluvu, 69]
Choose an action: 4
Add an element to insert after[Previous Node]: iluvu
Add an element to insert after[New Data]: enkk
Traceback (most recent call last): File "C:/Users/Admin/PycharmProjects/LinkedListIntro/IntroToLinkedList.py", line 94, in list.insertAfter(prevNode,newData) File "C:/Users/Admin/PycharmProjects/LinkedListIntro/IntroToLinkedList.py", line 29, in insertAfter newNode.next = prevNode.next AttributeError: 'str' object has no attribute 'next'
The issue is that you pass to insertAfter
two data values, but insertAfter
expects the first of those two to be a node instance, not a data value.
So here is what you could do:
Define a method find
which will find a given data value in the list and will return the node that has it:
def find(self, data):
current = self.head
while current:
if current.data == data:
return current
current = current.next
Now you can use this method in insertAfter
:
# The name of the argument changes:
def insertAfter(self, prevData, newData):
# Get the node where this data occurs:
prevNode = self.find(prevData)
if prevNode is None:
print("The given node must be in the linked list")
return
newNode = Node(newData)
newNode.next = prevNode.next
prevNode.next = newNode
It would be good to apply the same name change in the elif menu == 4
block, as the user inputs a value, not a node.