I need to print the items added.
class LinkedList:
def __init__(self, data= [(None,None)], number = None, letter = None, tail = None):
self.letter = data[0][0]
self.number = data[0][1]
self.tail = None if (len(data) == 1) else LinkedList(data[1:])
def insert(self, val):
new = LinkedList(val)
new.tail = self.data
self.data = new
def printer(self,curr):
while curr:
print(curr.letter, curr.number)
curr = curr.tail
new = LinkedList()
new.insert([("A", 1)])
new.insert([("B", 2)])
new.insert([("C", 3)])
new.printer(new)
you made a very small error,change your insert function to
def insert(self, val):
new = LinkedList(val)
new.tail = self.tail
self.tail = new
your LinkedList has no data attribute, its using tail as the "data" attribute
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've implemented a linked list in Python. The first item gets inserted properly. But the second one overwrites it in the head node. And after that it works just fine.
class Node:
def __init__(self):
self.data = None
self.next = None
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
self.iterator.next = Node()
self.iterator.data = value
self.iterator = self.head
def __str__(self):
l = []
while self.iterator.next is not None:
l.append(self.iterator.data)
self.iterator = self.iterator.next
self.iterator = self.head
return str(l)
t = LinkedList()
t.insert(2)
t.insert(4)
t.insert(8)
t.insert(6)
t.insert(10)
t.insert(12)
print(t)
Also in the str method how can I print the data if Head is the only node. (As Next of Head is None it will not enter the while loop.)
Here, you seem to overrwrite the data at self.iterator. Rather, you should set the data to the new node you created:
self.iterator.data = value
Fixed code:
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
new_node = Node()
new_node.data = value
self.iterator.next = new_node
self.iterator = self.head
Adding self.iterator.next = Node() inside the if statement of the method insert solved it for me:
class Node:
def __init__(self):
self.data = None
self.next = None
class LinkedList:
def __init__(self):
self.head = Node()
self.iterator = self.head
def isEmpty(self):
if self.head.data is None:
return True
def insert(self, value):
if self.isEmpty():
self.head.data = value
self.iterator.next = Node()
else:
while self.iterator.next is not None:
self.iterator = self.iterator.next
self.iterator.next = Node()
self.iterator.data = value
self.iterator = self.head
def __str__(self):
l = []
while self.iterator.next is not None:
l.append(self.iterator.data)
self.iterator = self.iterator.next
self.iterator = self.head
return str(l)
Output:
[2, 4, 8, 6, 10, 12]
I need help with the remove function. Can't remove the element ("B",2). If someone could show me how mine is wrong, or write me a new one I'd be ever so grateful.
class LinkedList:
def __init__(self, data= [(None,None)],number = None, letter = None, tail = None):
self.letter = data[0][0]
self.number = data[0][1]
self.tail = None if (len(data) == 1) else LinkedList(data[1:])
def insert(self, val):
new = LinkedList(val)
new.tail = self.tail
self.tail = new
def printer(self,curr):
while curr:
if curr.number is not None: print(curr.letter, curr.number)
curr = curr.tail
def remove(self, item):
if item == self.tail:
self.tail = self.tail.tail
return
previous = self.tail
current = self.tail.tail #i.e. current is set one in front
while current:
if current == item:
previous.tail = current.tail
return
previous = current
current = current.tail
new = LinkedList()
new.insert([("A", 1)])
new.insert([("B", 2)])
new.insert([("C", 3)])
new.printer(new)
print("---------")
new.remove([("B", 2)])
new.printer(new)
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]