Remove method in Python LinkedList using an index - python

class Node(object):
def __init__(self, data, next):
self.data = data
self.next = next
class LinkedList(object):
head = None
tail = None
def print_list(self):
node = self.head
while node:
print node.data,
node = node.next
def add_front(self, data):
node = Node(data, None)
if self.head is None:
self.head = self.tail = node
else:
self.tail.next = node
self.tail = node
def remove(self, index):
curr_node = self.head
prev_node = None
while curr_node and index>=0:
if index == 0:
if prev_node is not None:
prev_node.next = curr_node.next
else:
self.head = curr_node.next
index = index - 1
prev_node = curr_node
curr_node = curr_node.next
So, I wanted to implement a remove method using index in python but it does not seem to be working. I think I'm messing something with replacing the nodes but can't figure out which one. So a little help needed here.

Related

error in creating a linked list using python

I am new to data structures.Tried to create a linkled list with a print function,but when running the program it is throwing an error stating "add_link takes one positional argument but 2 were given".Below is the code.Please help me out. thanks in advance
class node:
def __init__( self ,value, Next = None):
self.value = value
self.Next = None
newnode = None
def add_link(self,data):
if(self.Next == None):
self.Next = node(data)
newnode = self.Next
else:
newnode.Next = node(data)
newnode = newnode.Next
def print(self):
if(self.Next !=None):
print(self.node)
self.next.print()
# main
link = node(10)
link.add_link(20)
link.add_link(30)
link.add_link(40)
link.print()
You need to add self as an argument to the add_link() function:
def add_link(self, data):
if(self.Next == None):
self.Next = node(data)
newnode = self.Next
else:
newnode.Next = node(data)
newnode = newnode.Next
It will be better to create Node as a seprate class/structure, and LinkedList as different.
So that we can implement methods according to class.
class Node:
"""
#Summary: Node has a set of information and address to the next node.
"""
def __init__(self, data) -> None:
self.data = data
self.next = None
class SinglyLinkedList:
def __init__(self, item:Node) -> None:
# Head or start node for Singly Linked List
self.head = item
def add(self, new_item:Node) -> None:
"""
#Summary: Adde new item to Singly Linked List
#Param new_item(Node): New node item
#Return (None)
"""
# Check if Linked list is emplty or not.
if self.head == None:
self.head = new_item
else:
# Add a new item to an end.
last_node = self.head
while last_node.next != None:
last_node = last_node.next
last_node.next = new_item
def print(self):
"""Print Linked List"""
if self.head == None:
print("No item in Linked list")
else:
print("Linked List :")
tmp_node = self.head
while True:
print(tmp_node.data, end=" ")
if tmp_node.next == None:
break
tmp_node = tmp_node.next
print()
# Create Node as a Head node.
item01 = Node(10)
obj = SinglyLinkedList(item01)
obj.add(Node(20))
obj.add(Node(30))
obj.add(Node(40))
obj.print()

what is wrong with this code? adding node after a given value in list

i am using a while to add a node to my linked list after a value provided.
but it is not working accordingly.
I have done print command inside while loop it's showing that it works fine as I want, but when I am printing list it's not.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LInkedList:
def __init__(self):
self.head = None
def print_list(self):
cur_node = self.head
while cur_node:
print(cur_node.data)
cur_node = cur_node.next
def apppend(self, data):
new_node = Node(data)
if self.head is None:
new_node = self.head
return
last_node = self.head
while last_node.next is not None:
last_node = last_node.next
last_node.next = new_node
def prepend(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def add_after_node(self, after, data):
new_node = Node(data)
this_node = self.head
while this_node:
if this_node.data == after:
new_node.next = this_node.next
this_node.next = new_node
# print(this_node.data) this shows that is updating properly
this_node = this_node.next
new_list = LInkedList()
new_list.prepend(10)
new_list.prepend(20)
new_list.prepend(30)
new_list.prepend(20)
new_list.add_after_node(20, 50)
new_list.print_list()
I want that 50 should be added after each 20 in the list.
for example:
input :- 20 30 20 10
output :- 20 50 30 20 50 10
right now it is printing 20 50 10 with print_list function I don't know why?

Python LinkedList Garbage Collector

My question is, will the object Node(3) still be in RAM memory once we reach the end of remove() function ? If no, when is it deleted from RAM memory ?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def add(self, data):
if self.head is None:
self.head = Node(data)
else:
curr_node = self.head
while (curr_node.next):
curr_node = curr_node.next
curr_node.next = Node(data)
def remove(self, data):
if self.head is not None:
if self.head.data == data:
self.head = self.head.next
else:
curr_node = self.head
while curr_node.next is not None:
if curr_node.next.data == data:
curr_node.next = curr_node.next.next
break
curr_node = curr_node.next
l = LinkedList()
l.add(2)
l.add(3)
l.add(4)
l.remove(3)
# program going on ...

Node getting added twice into list

This is my code ignore if any of the spacing is wrong the code works perfectly fine in python.
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return "Node({})".format(self.value)
def getNext(self):
return self.next
def getValue(self):
return self.value
def setNext(self, new_next):
self.next = new_next
def setValue(self, new_value):
self.value = new_value
__repr__ = __str__
class OrderedLinkedList:
def __init__(self):
self.head=None
self.tail=None
self.count = 0
def __str__(self):
temp=self.head
out=[]
while temp:
out.append(str(temp.value))
temp=temp.next
out=' '.join(out)
return ('Head:{}\nTail:{}\nList:{}'.format(self.head,self.tail,out))
__repr__=__str__
def add(self, value):
#write your code here
if self.head == None:
new_node = Node(value)
self.head = new_node
self.tail = self.head
self.head.setNext(self.tail)
if self.head.value > value:
new_node = Node(value)
new_node.value = value
new_node.next = self.head
self.head = new_node
else:
new_node = Node(value)
self.tail.setNext(new_node)
self.tail = new_node
self.count += 1
def pop(self):
#write your code here
if self.head == None:
return 'List is empty'
if len(self) == 1:
value = self.head.getValue()
self.head = None
self.tail = None
self.count = 0
return value
current = self.head
while current.next is not self.tail:
current = current.getNext()
value = self.tail.getValue()
self.tail = current
self.tail.next = None
self.count -= 1
return value
def isEmpty(self):
#write your code here
return self.head == None
def __len__(self):
#write your code here
return self.count
The only problem I have with it is that when I first use the function add it adds the number twice. Below is the outcome when I first call add every time after that it adds the number only once. How can I fix it so it only adds the first number once instead of twice.
>>> x=OrderedLinkedList()
>>> x.add(2)
>>> print(x)
Head:Node(2)
Tail:Node(2)
List:2 2
add(item) adds a new Node with value=item to the list making sure that the ascending order is preserved. It needs the item and returns nothing.
Yep, it adds the first number twice since you need fix a bug in your add method by adding an elif:
def add(self, value):
if self.head == None:
new_node = Node(value)
self.head = new_node
self.tail = self.head
# self.head.setNext(self.tail) ## remove to prevent infinity loop
elif self.head.value > value:
new_node = Node(value)
new_node.value = value
new_node.next = self.head
self.head = new_node
else:
new_node = Node(value)
self.tail.setNext(new_node)
self.tail = new_node
Since, if the head es None once the data is added then the next conditional always will execute one of the two parts on if or else.

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