I tried to remove the banana from the method remove_by_value, but it was unable to remove.
class LinkedList:
def __init__(self):
self.head = None
def insert_at_end(self, data):
if self.head is None:
self.head = Node(data, None)
return
itr = self.head
while itr.next:
itr = itr.next
itr.next = Node(data, None)
def insert_values(self, data_list):
self.head = None
for data in data_list:
self.insert_at_end(data)
def remove_by_value(self,data):
itr = self.head
if itr is None:
return
if itr.data == data:
itr.next = itr.next
return
while itr:
if itr.next.data == data:
itr.next = itr.next.next
break
itr = itr.next
if __name__ == '__main__':
ll = LinkedList()
ll.insert_values(["banana","mango","grapes","orange"])
ll.print() # from method to show all object.
ll.remove_by_value2("banana")
ll.print()
output:
banana=>mango=>grapes=>orange=>
banana=>mango=>grapes=>orange=>
please look here at the part of the remove node:
https://www.tutorialspoint.com/python_data_structure/python_linked_lists.htm
this is how you suppose to implement a linked list in python :)
let me know if you have more questions about it
Related
I'm trying to solve merge two sorted linkedlist problem using dummy head technique. For some reason I have an error coming from passing an argument to my dummy head holder. The output suppose to merge both linkedlist like this: 1-> 1-> 2-> 3-> 7-> None
I would be happy if you please guide which data needs to pass in my dummy head variable? Thanks in advance! This is the error I have:
dummy = LinkedList()
TypeError: __init__() missing 1 required positional argument: 'data
Here's my complete code:
class LinkedList:
def __init__(self, data):
self.data = data
self.next = None
def print_list(head: LinkedList) -> None:
while head:
print(head.data, end=" -> ")
head = head.next
print("None")
def merge_lists(headA, headB):
dummy = LinkedList()
curr = dummy
while headA != None and headB != None:
if headA.data < headB.data:
curr.next = headA
headA = headA.next
else:
curr.next = headB
headB = headB.next
curr = curr.next
if headA != None:
curr.next = headA
else:
curr.next = headB
return dummy.next
node1 = LinkedList(1)
node1.next = LinkedList(2)
node1.next.next = LinkedList(7)
node2 = LinkedList(1)
node2.next = LinkedList(3)
print(merge_lists(node1, node2)) # 1-> 1-> 2-> 3-> 7-> None
Since it is a dummy node, and you never ever use the data attribute of that node, you can pass anything as argument, like None:
dummy = LinkedList(None)
Alternatively, you could specify that providing an argument is optional, and define the constructor as follows:
class LinkedList:
def __init__(self, data=None):
self.data = data
self.next = None
Unrelated, but at the end of your script you have:
print(merge_lists(node1, node2))
This will print the object reference. You probably wanted to call the function you have defined for this purpose:
print_list(merge_lists(node1, node2))
If you want print to work like that, then instead of the print_list function, enrich LinkedList with an __iter__ method to ease iteration over the values in the list, and a __repr__ or __str__ method as follows:
class LinkedList:
def __init__(self, data=None):
self.data = data
self.next = None
def __iter__(self):
head = self
while head:
yield head.data
head = head.next
yield None # Optional
def __repr__(self):
return " -> ".join(map(str, self))
...and then you can do
print(merge_lists(node1, node2))
class node:
def __init__(self, data):
self.data = data
self.next = None
class linkedList:
def __init__(self):
self.head = None
def insertNode(self, data):
newnode = node(data)
if self.head is None:
self.head = newnode
else:
current = self.head
while current.next is not None:
current = current.next
current.next = newnode
def printLL(self):
current = self.head
while current.next is not None:
print(current.data, end='----->')
current = current.next
print(current.data, '------>None')
def sortLL(self):
arr=[]
current = self.head
while current.next is not None:
arr.append(current.data)
current = current.next
arr.append(current.data)
arr.sort()
self.head = None
for i in arr:
self.insertNode(i)
def mergeTwoSortedLL(l, l2):
current1 = l.head
current2 = l2.head
l3 = linkedList()
while current1 is not None and current2 is not None:
if current1.data < current2.data:
l3.insertNode(current1.data)
current1 = current1.next
else:
l3.insertNode(current2.data)
current2 = current2.next
if current1 is None:
while current2.next is not None:
l3.insertNode(current2.data)
current2 = current2.next
l3.insertNode(current2.data)
else:
while current1.next is not None:
l3.insertNode(current1.data)
current1 = current1.next
l3.insertNode(current1.data)
return l3
l = linkedList()
l.insertNode(9)
l.insertNode(18)
l.insertNode(11)
l.insertNode(15)
l.insertNode(1)
l.insertNode(8)
l.sortLL()
l.printLL()
l2 = linkedList()
l2.insertNode(9)
l2.insertNode(18)
l2.insertNode(11)
l2.insertNode(15)
l2.insertNode(1)
l2.insertNode(8)
l2.sortLL()
l2.printLL()
mergeTwoSortedLL(l,l2).printLL()
class Node:
def __init__(self,data = None, Next = None):
self.data = data
self.Next = Next
class LinkedList:
def __init__(self):
self.head = None
def insertAtBegining(self,data):
node = Node(data,self.head)
self.head = node
def Print(self):
if self.head == None:
print("Empty Linkelist")
itr = self.head
lstr = ''
while itr:
lstr += str(itr.data) + '-->'
itr = itr.next
print (lstr)
if __name__ == '__main__':
obj1 = LinkedList()
obj1.insertAtBegining(5)
obj1.insertAtBegining(10)
obj1.insertAtBegining(15)
obj1.Print()
I am getting error in Node class saying it does not have next attribute.
It doesn't have next, it has Next, which are different, you can either change itr.next to itr.Next, or (better, to be consistent with your naming) change your Node definition to this:
class Node:
def __init__(self, data = None, next = None):
self.data = data
self.next = next
I'm trying to create 2 single linked lists and find the intersection between them. I'm getting errors such as NameError: obj is not defined for the LinkedList line and would like a working solution. How do I make this work? What am I doing wrong? Am I even close? What is the meaning of life? This is in python.
class IntersectSolution:
def intersect(sll_a, sll_b):
b_x_node = sll_b
while sll_b and not sll_a.search(sll_b.get_data()):
sll_b.get_next()
b_x_node = sll_b
if b_x_node == None:
print("No intersections between nodes.")
print("Intersection node is: {}".format(b_x_node))
class Node:
def __init__(self, data = None, next_node = None):
self.data = data
self.next_node = next_node
def get_data(self):
return self.data
def get_next(self):
return self.next_node
def set_next(self, new_node):
self.next_node = new_node
class LinkedList(obj):
def __init__(self, head = None):
self.head = head
def insert(self, data):
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.get_next
return count
def search(self, data):
current = self.head
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
return current
def delete(self, data):
current = self.head
previous = None
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
previous = current
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
if previous is None:
self.head = current.get_next()
else:
previous.set_next(current.get_next())
a = LinkedList(Node)
b = LinkedList(Node)
for i in range(1, 15, 2):
a.insert(i)
for j in range(23, 8, -3):
b.insert(j)
ISoln = IntersectSolution
ISoln.intersect(a,b)
You can concatenate both linked-lists by implementing a custom __add__ method and then finding the values in the concatenated result that exist in both original lists:
class LinkedList:
def __init__(self, _val=None):
self.val = _val
self._next = None
def insert(self, _val):
if self.val is None:
self.val = _val
else:
getattr(self._next, 'insert', lambda x:setattr(self, '_next', LinkedList(x)))(_val)
def __iter__(self): #iterate over all values in list
yield self.val
yield from [[], self._next][bool(self._next)]
def __add__(self, _list): #concatenate two linkedlists
_l = self.__class__()
for i in _list:
_l.insert(i)
for i in self:
_l.insert(i)
return _l
def __contains__(self, _val): #check if a value exists in the list
if self.val is None:
return False
return True if self.val == _val else getattr(self._next, '__contains__', lambda _:False)(_val)
#classmethod
def intersection(cls, _a, _b):
_result = cls()
for i in (_a+_b):
if i in _a and i in _b and i not in _result:
_result.insert(i)
return _result
l = LinkedList()
for i in range(10):
l.insert(i)
l1 = LinkedList()
for i in range(6, 14):
l1.insert(i)
_intersection = LinkedList.intersection(l, l1)
print([i for i in _intersection])
Output:
[6, 7, 8, 9]
I've hit a snag working with classes on a linked list. My code below:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Item(object):
def __init__(self, data, next_item = None):
self.data = data
self.next_item = next_item
def get_item(self):
return self.data
def set_next(self, setnext):
self.next_item = setnext
def get_next(self):
return self.next_item
class LinkedList(object):
def __init__(self):
self.head = None
def add(self,item):
temp = Item(item)
temp.set_next(self.head)
self.head = temp
def find(self, item):
current = self.head
while current != None:
if current == item:
print "Found It!"
else:
current = current.get_next()
def print_list(self):
node = self.head
while node:
print node.get_item()
node = node.get_next()
def size(self):
counter = 0
current = self.head
while current != None:
counter += 1
current = current.get_next()
print counter
def insert(self,item,lpos):
current = self.head
while current != lpos:
current = current.get_next()
if current == None:
return None
else:
item_insert = Item(item, lpos.next_item())
lpos.set_next(item_insert)
myList = LinkedList()
myList.add(1)
myList.add(2)
myList.add(3)
myList.insert(8,2)
When i run this code the method (insert) fails with the following error:
Traceback (most recent call last):
File "main.py", line 72, in <module>
myList.insert(8,2)
File "main.py", line 56, in insert
item_insert = Item(item, lpos.Item.next_item())
AttributeError: 'int' object has no attribute 'Item'
The insert method will allow you to add a node to your linked list at a specified point, and carry out with rearranging the proper pointers, considering the insert.
please advise!
You haven't pay attention to the difference between 'item' and 'index'. The index is a unsigned digit present for the position of the item in the list, however the item is a node in the list.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Item(object):
def __init__(self, data, next_item = None):
self.data = data
self.next_item = next_item
def get_item(self):
return self.data
def set_next(self, setnext):
self.next_item = setnext
def get_next(self):
return self.next_item
class LinkedList(object):
def __init__(self):
self.head = None
def add(self,item):
temp = Item(item)
temp.set_next(self.head)
self.head = temp
def find(self, item):
current = self.head
while current != None:
if current == item:
print "Found It!"
else:
current = current.get_next()
def print_list(self):
node = self.head
while node:
print node.get_item()
node = node.get_next()
def size(self):
counter = 0
current = self.head
while current != None:
counter += 1
current = current.get_next()
print counter
def insert(self,item,lpos):
if lpos == 0:
item_insert = Item(item, self.head)
self.head = item_insert
return
current = self.head.get_next()
previous = self.head
index = 1
while index != lpos:
index += 1
previous = current
current = current.get_next()
if current == None:
return None
item_insert = Item(item, current)
previous.set_next(item_insert)
myList = LinkedList()
myList.add(1)
myList.add(2)
myList.add(3)
myList.insert(8,0)
myList.print_list()
lpos is an index, which type is int. But what you want to set is Item.next_item(), of course it doesn't work. Change:
# lpos is Int
item_insert = Item(item, lpos.next_item())
to:
# use Item instance to do your stuff
item_insert = Item(item, current.next_item())
Anyway, your implementation of insert should not be correct.
I've implemented a Linked List class and I have a selectionSort and insertionSort function created that works on regular lists. I need to get selectionSort and insertionSort to work on linked lists, but I'm not sure where to even start, if I'm being honest.
Here's my linked list class:
class Node:
def __init__(self, initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self, newnext):
self.next = newnext
class unorderedList:
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
def add(self, item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self, item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self, item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext()
Here's my code for selectionSort and insertionSort. They work just fine on regular lists, but I'm having a lot of trouble figuring out where to start to get them to work on a linkedlist (unordered list).
def selectionSort(alist):
for fillslot in range(len(alist)-1,0,-1):
positionOfMax = 0
for location in range(1,fillslot+1):
if alist[location]>alist[positionOfMax]:
positionOfMax = location
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
def insertionSort(alist):
for index in range(1,len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position] = alist[position-1]
position = position-1
alist[position] = currentvalue
Any suggestions/hints would be greatly appreciated.
I tried to implement insertionSort, The code is readable. SelectionSort should be similar, try to implement it.
def insertionSort(h):
if h == None:
return None
#Make the first node the start of the sorted list.
sortedList= h
h=h.next
sortedList.next= None
while h != None:
curr= h
h=h.next
if curr.data<sortedList.data:
#Advance the nodes
curr.next= sortedList
sortedList= curr
else:
#Search list for correct position of current.
search= sortedList
while search.next!= None and curr.data > search.next.data:
search= search.next
#current goes after search.
curr.next= search.next
search.next= curr
return sortedList
def printList(d):
s=''
while d:
s+=str(d.data)+"->"
d=d.next
print s[:-2]
l= unorderedList()
l.add(10)
l.add(12)
l.add(1)
l.add(4)
h= l.head
printList(h)
result= insertionSort(l.head)
d= result
printList(d)
Output:
4->1->12->10
1->4->10->12