LinkedList delete functionality is deleting 2 nodes - python

I'm creating my own linkedList implementation and am somehow deleting 2 nodes at once. I do not understand why. I have tried deleting different integers and it seems to really like to delete the second entry in the list.
When I don't use the delete method the list traverses correctly. This leads me to believe that I am deleting incorrectly. I am keeping track of the previous node with the place_node various.
class LinkedList:
def __init__(self):
self.head = None
def prepend(self,data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def traversal(self):
temp = self.head
while temp is not None:
print(temp.data)
temp = temp.next
def append(self,data):
new_node = Node(data)
place_node = None
temp = self.head
while temp is not None:
place_node = temp
temp = temp.next
new_node.next = place_node.next
place_node.next = new_node
def delete(self,data):
new_node = Node(data)
temp = self.head
while temp is not None:
if temp.data == data:
break
place_node = temp
temp = temp.next
place_node.next = temp.next
class Node:
def __init__(self,data):
self.data = data
self.next = None
ehren = LinkedList()
ehren.prepend(5)
ehren.prepend(3)
ehren.prepend(8)
ehren.append(6)
print(" delete the number")
ehren.delete(6)
print("linked list***********")
ehren.traversal()

The delete method should be implemented like this:
def delete(self, data):
prev = None
temp = self.head
while temp is not None:
if temp.data == data:
if prev is None: # Handle the case when we are deleting the head which has no previous node
self.head = self.head.next
else:
prev.next = temp.next
break
prev = temp
temp = temp.next
Since this is a singly-linked-list, you need to keep track of the node before the target, and to delete means to set the next pointer of the previous node to the next pointer of the node to be deleted, thus making the selected node disappear.

Related

Why does the latest "append" in my python doubly linked list have no effect?

This is part of my doubly linked list deque python code.
The 'appendleft' function written almost similar to the 'append' function is normally output. Why is the last 'append('apple')' code not output normally in the 'Group_of_append' function?
class Node:
def __init__(self,item,prev,next):
self.item = item
self.prev = prev
self.next = next
class deque:
def __init__(self,name):
self.name = name
self.head = Node(None,None,None)
self.tail = Node(None,self.head,None)
self.head.next = self.tail
self.size = 0
def append(self,item):
current = self.head
new_node = Node(item,None,None)
while current.next != None:
current = current.next
current.next = new_node
new_node.prev = current
self.tail = new_node
self.size += 1
return
def appendleft(self,item):
current = self.tail
new_node = Node(item,None,None)
while current.prev != None:
current = current.prev
current.prev = new_node
new_node.next = current
self.head = new_node
self.size += 1
return
def print_list(self):
p = self.head
while p.next != None:
if p.item == None:
pass
else:
print(p.item,end=' ')
p = p.next
def Group_of_append(self):
print('Group_of_append')
self.append('graphe')
self.append('cherry')
self.append('apple')
self.appendleft('watermelon')
self.appendleft('strawberry')
self.print_list()
print(" ")
deq = deque('name')
deq.Group_of_append()
the result is
strawberry watermelon graphe cherry
The last append code on Group_of_append, self.append('apple') have no effect.
While defining the 'append' function, I thought that there would be no output due to one more size being insufficient.
So, I changed 'append' function on deque like this
def append(self,item):
self.size += 1
current = self.head
new_node = Node(item,None,None)
while current.next != None:
current = current.next
current.next = new_node
new_node.prev = current
self.tail = new_node
self.size += 1
return
But the result was same(still the lastest 'append' function doesn't print anything)
strawberry watermelon graphe cherry
Your appends work fine. Problem lies in your print_list function which stops when p.next is None. Which means your last element will not be printed because its next is None.
All in all, your logic for this list is very strange and could use a lot of rework, it would make finding mistakes like this one a lot easier for you. For example, this iterating through the whole list when appending even though you have both head and tail readily available in the deque object.

Remove Duplicates from unsorted Linked list(python)

In my last code for removing duplicates, the method removeDup isn't working.
The last print(ll.display()) is printing the previous linked list.
I was hoping it to print only unique nodes. What am I missing in removeDups method?
I can't figure out. What is happening in the code here?
class Node:
def __init__(self,data = None):
self.data = data
self.next = None
def __repr__(self):
return self.data
class LList:
def __init__(self):
self.head = None
def display(self):
current = self.head
node = []
while current != None:
node.append(current.data)
current = current.next
return node
def append(self, data):
elem = Node(data)
if self.head == None:
self.head = elem
else:
current = self.head
while current.next != None:
current = current.next
current.next = elem
def add_atFront(self, data):
elem = Node(data)
if self.head == None:
self.head = elem
else:
elem.next = self.head
self.head = elem
def removeDup(self):
current = self.head
previous = None
elems = []
while current != None:
if current.data in elems:
previous.next= current.next
else:
elems.append(current.data)
previous = current
current = current.next
ll= LList()
print(ll.display())
ll.append(65)
ll.append(7)
ll.add_atFront('65')
ll.add_atFront('Bare')
ll.insert('10',0)
ll.insert('7',2)
print(ll.display())
ll.removeDup()
print(ll.display())
Your removeDup works fine, the issue is that 65 and '65' are not duplicates, so you should not expect removeDup to dedup them. The same goes for 7 and '7'. Also, note you never defined the insert method, but I'll assume that's just a copy error.

AttributeError: 'NoneType' object has no attribute 'next' and Function missing 2 required positional arguments: 'x' and 'y'

I am trying to write a program to insert a node at a specific position and the errors I am getting are,
AttributeError: 'NoneType' object has no attribute 'next'
and also
Function missing 2 required positional arguments: 'x' and 'y'
Code:
class SinglyLinkedListNode:
def __init__(self, data):
self.data = data
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
self.tail = None
def insertnode_end(self, data):
node = SinglyLinkedListNode(data)
if not self.head:
self.head = node
else:
self.tail.next = node
self.tail = node
def print_ll(self):
temp = self.head
while temp is not None:
print(temp.data, end=" ")
temp = temp.next
def insertNode_pos(self, data, pos):
new_node = SinglyLinkedListNode(data)
if (pos == 0):
new_node.next = self.head
self.head = new_node
temp = self.head
while temp.next is not None:
for _ in range(pos - 1):
temp = temp.next
new_node.next = temp.next
temp.next = new_node
llist_count = int(input())
llist = SinglyLinkedList()
for _ in range(llist_count):
llist_item = int(input())
llist.insertnode_end(llist_item)
data = int(input())
pos = int(input())
llist.insertNode_pos(data, pos)
llist.print_ll()
I don't see x and y in your code. It is helpful if you include the full traceback. It seems that your function is hitting the last node in the list, whose next item is None. Obviously, None doesn't have the next and data attributes.
Meanwhile, I modified your insertNode_pos function. One important line here is return if pos == 0. Your function doesn't need to continue in that case.
def insertNode_pos(self, data, pos):
new_node = SinglyLinkedListNode(data)
if pos == 0:
new_node.next = self.head
self.head = new_node
return
temp = self.head
for iter in range(pos):
if iter == 0:
temp = self.head
else:
temp = temp.next
new_node.next = temp.next
temp.next = new_node
One more note is that implementing __str__ is a more common practice for printing content of your data:
def __str__(self):
output = []
temp = self.head
while temp is not None:
output.append(str(temp.data))
temp = temp.next
return ",".join(output)
Then you can simply say print(llist)

why is this not giving an output and the kernel is going on running as if it has gone under some loop?

learning how to make linked lists?
pls provide with better solution if possible.
added push ,insertafter ,printlist,append functions.
learning how to make linked lists?
pls provide with better solution if possible.
added push ,insertafter ,printlist,append functions.
class Node:
def __init__(self,data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def push(self,new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
def insertAfter(self,prev_node,new_data):
if prev_node is None:
print('Enter valid previous node data')
return
new_node = Node(new_data)
new_node.next = prev_node.next
prev_node.next = new_data
def append(self,new_data):
new_node= Node(new_data)
if self.head is None:
self.head = new_node
last = self.head
#while last.next!= None:
#temp = last.next
#last =temp.next
while last.next:
last = last.next
last.next = new_node
def printList(self):
temp = self.head
while temp:
print(temp.data)
temp = temp.next
if __name__ =='__main__':
llist = LinkedList()
llist.append(7)
llist.append(8)
llist.push(5)
llist.insertAfter(Node(5),6)
llist.printList()
The fix:
def append(self,new_data):
new_node= Node(new_data)
if self.head is None:
self.head = new_node
return # <- this is the fix
...
Without this return statement, you go to this newly added node and assign its .next to itself. With this circular reference, the next .append() gets into infinite loop
The problem is in the append method. When you append the first node, self.head is None, so you execute:
self.head = new_node
But then you continue trying to find the last node, which in this case will also end up being self.head:
last = self.head
#while last.next!= None:
#temp = last.next
#last =temp.next
while last.next:
last = last.next
As a result, when you execute this line:
last.next = new_node
You are effectively setting new_node.next = new_node, which causes the next call to append to go into an infinite loop.

NoneType Error: Python Doubly Linked List

Getting caught up in a solution to NoneType errors stemming from using my functions add and append in the below code to an empty Double_list class object. Best way to avoid?
class Dbl_Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class Double_list:
def __init__(self): # Creates initial list w/ head and tail as None
self.head = None
self.tail = None
def add(self, item): # adds node to beginning/head of list
temp = self.head
self.head = Dbl_Node(item)
temp.prev = self.head
self.head.next = temp
def append(self, item): # adds node to end/tail of list
temp = self.tail
self.tail = Dbl_Node(item)
self.tail.prev = temp
temp.next = self.tail
You're initialising head and tail to None, but then trying to set prev and next members on them when inserting the first Dbl_Node.
def add(self, item):
temp = self.head # on the first call to "add", self.head is None
# (as set in __init__) so temp is now None
self.head = Dbl_Node(item) # create a new node and assign it to self.head
# this is fine
temp.prev = self.head # this says assign the new node in self.head to the "prev"
# member of temp, however temp is None so the temp.prev part
# throws the error
You should check for this case
def add(self, item): # adds node to beginning/head of list
temp = self.head
self.head = Dbl_Node(item)
if temp is not None:
temp.prev = self.head
An alternate solution is to start with "dummy" nodes for the head and tail:
def __init__(self):
self.head = Dbl_Node(None)
self.tail = Dbl_Node(None)
self.head.next = self.tail
self.tail.prev = self.head
And then insert items in between these nodes
def add(self, item):
temp = self.head.next
self.head.next = Dbl_Node(item)
temp.prev = self.head.next
self.head.next.next = temp
Although I find this tends to needlessly complicate things a bit.
def append(self, item): # adds node to end/tail of list
temp = self.tail
self.tail = Dbl_Node(item)
self.tail.prev = temp
temp.next = self.tail
This will always raise a NoneType exception because
self.tail is initially None then you assign a reference
to it (None) to temp and try to assign something to
None. Won't work.
YOu need to probably firstly assign a new object reference to self.tail

Categories

Resources