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()
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()
This is my node class and Mylist class
class Node:
def __init__(self, data=None, next=None):
self.data = data
self.next = next
class MyList():
def __init__(self,head=None):
self.head = head
def showList(self):
temp = self.head
while (temp):
print(temp.data)
temp = temp.next
if self.head is None:
print("Empty List")
This is my showeven number function
def showeven(even):
head = None
while even:
if even.data % 2 == 0:
new_Node = Node(even.data, None)
if head is None:
tail = new_Node
head = new_Node
else:
tail.next = new_Node
tail = new_Node
MyList(head).showList()
Can you guys help me create a tester class or some sort of thing for this
You can simply write something like this.
def print_even_nodes(self):
traverse = self.head
while (traverse != None):
if (traverse.data % 2 == 0):
print(traverse.data)
traverse = traverse.next
It is pretty much similar to printing the whole singly linked list, the only key difference is that we check if that particular node (node.data field) is divisible by 2. If it is true we print out the element else we go to the next node.
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.
Here are the three classes: the node, the doubly linked list, and a sorted list which implement on the doubly linked list. Here is my code:
class DLLNode(object):
def __Init__ (self, data, prev_node=None, next_node=None):
self.data=data
self.prev_node=prev_node
self.next_node=next_node
def __str__(self):
return str(self.data)
class DoublyLinkedList(object):
def __init__(self, head=None, tail=None):
self.head=head
self.tail=tail
self.size=0
def add_to_head(self, data):
newNode = DLLNode(data)
if self.head==None:
self.head=self.tail=newNode
self.head.prev_node=self.tail.next_node=None
else:
self.head.prev_node=newNode
newNode.next_node=self.head
self.head=newNode
def add_to_tail(self, data):
newNode=DLLNode(data)
if self.head==None:
self.head=self.tail=newNode
self.head.prev_node=self.tail.next_node=None
else:
self.tail.next_node=newNode
newNode.prev_node=self.tail
self.tail=newNode
self.tail.next_node=None
def remove_head(self):
node=self.head
if self.head==self.tail:
self.prev_node=self.next_node=self.head=self.tail=None
return
if self.head!=self.tail:
node=node.next_node
node.prev_node=None
self.head=node
def remove_tail(self):
node=self.tail
if self.head==self.tail:
self.prev_node=self.next_node=self.head=self.tail=None
return
if self.head!=self.tail:
self.tail=node.prev_node
self.tail.next_node=None
def index(self,element):
current = self.head
while current != None:
if current.data == element:
return current.position
else:
current = current.next
return -1
class SortedList(object):
def __init__(self, sequence = []):
if len(sequence)==0:
self.head = None
self.tail = None
else:
cur_node = None
prev_node = None
sequence.sort()
sequence.reverse()
for element in sequence:
prev_node = cur_node
cur_node = DLLNode(element, cur_node, prev_node)
self.head = cur_node
self.tail = DLLNode(sequence[0])
For the sorted list class I need to create an add and remove function. However, I dont really know how to do it. Could anyone let me know?
I am constructing a doubly linked list and I am struggling on construct a doubly linked list iterator method in PYTHON.
This is my code so far
class DoubleListNode:
def __init__(self,data):
self.data=data
self.prev = None
self.next= None
class ListIterator:
def __init__(self):
self._current = self.head
def __iter__(self):
return self
def next(self):
if self.size == 0 :
raise StopIteration
else:
item = self._current.data
self._current=self._current.next
return item
class DoublyLinkedList:
def __init__(self):
self.head= None
self.tail= None
self.size = 0
def add(self,data):
newnode= DoubleListNode(data)
self.size+=1
if self.head is None:
self.head = newnode
self.tail = self.head
elif data < self.head.data: # before head
newnode.next = self.head
self.head.prev= newnode
self.head= newnode
elif data > self.tail.data: # at the end
newnode.prev= self.tail
self.tail.next= newnode
self.tail=newnode
else:
curNode = self.head
while curNode is not None and curNode.data < data:
curNode=curNode.next
newnode.next= curNode
newnode.prev=curNode.prev
curNode.prev.next= newnode
curNode.prev=newnode
def remove(self,data):
curNode=self.head
while curNode is not None and curNode.data!= data:
curNode= curNode.next
if curNode is not None:
self.size -= 1
if curNode is self.head:
self.head= curNode.next
else:
curNode.prev.next=curNode.next
if curNode is self.tail:
self.tail=curNode.prev
else:
curNode.next.prev=curNode.prev
When I run a test it said TypeError: iteration over non-sequence. Did I do something wrong ?
As posted, the code doesn't initialize (i.e. self.head isn't defined).
But overall, you are on the right track. Take a look at the source for Python's collections.OrderedDict for a worked-out example of traversing a doubly linked list.
Here's a simplified example:
class Link:
def __init__(self, value, prev=None, next=None):
self.value = value
self.prev = prev
self.next = next
def __iter__(self):
here = self
while here:
yield here.value
here = here.next
def __reversed__(self):
here = self
while here:
yield here.value
here = here.prev
if __name__ == '__main__':
a = Link('raymond')
b = Link('rachel', prev=a); a.next=b
c = Link('matthew', prev=b); b.next=c
print 'Forwards:'
for name in a:
print name
print
print 'Backwards:'
for name in reversed(c):
print name
I think there are two important things to fix.
First, your DoublyLinkedList class doesn't have an __iter__ method. You probably want to create one that returns a ListIterator instance. Perhaps you're trying to do this manually, but this would be the normal approach.
Second, you need to fix the code in your ListIterator to work properly. Currently your __init__ method doesn't initialize things correctly, and your next method tries to access member variables like size that don't exist.
Here's an implementation that I think will work:
def ListIterator(object):
def __init__(self, node):
self.current = node
def __iter__(self):
return self
def next(self):
if self.current is None:
raise StopIteration()
result = self.current.data
self.current = self.current.next
return result
class DoublyLinkedList(object):
# all your current stuff, plus:
def __iter__(self):
return ListIterator(self.head)
As a side note, in your current code you're defining classes with no bases. This is fine in Python 3 (where object will be the base by default), but in Python 2 this will result in getting an "old-style" class. Old-style classes are deprecated, and you'll find that some language features won't work properly with them (though not any of the features involved in iteration, as far as I know). On the other hand, if you are already using Python 3 then you need to define a __next__ method in the iterator class, rather than next (without the underscores).
Here is an example for Doubly Linked List class.
class Node:
def __init__(self, val):
self.data = val
self.next = None
self.prev = None
class LinkedList:
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def insert(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.head.prev = newNode
newNode.next = self.head
self.head = newNode
self.count += 1
def insertToEnd(self, val):
newNode = Node(val)
if self.count == 0:
self.head = newNode
self.tail = newNode
else:
self.tail.next = newNode
newNode.prev = self.tail
self.tail = newNode
self.count += 1
def search(self, val):
p = self.head
while p is not None:
if p.data == val:
return p
p = p.next
def delete(self, val):
curNode = self.head
while curNode != None:
if curNode.data == val:
if curNode.prev != None:
curNode.prev.next = curNode.next
else:
self.head = curNode.next
if curNode.next != None:
curNode.next.prev = curNode.prev
else:
self.tail = curNode.prev
self.count -= 1
curNode = curNode.next
def show(self):
s = ""
p = self.head
while p is not None:
s += str(p.data) + ' ';
p = p.next
print(s + "| count: " + str(self.count))
Based on what you post, may I suggest:
class ListIterator:
# other stuff ...
def __iter__(self):
while self._current:
yield self._current.data
self._current = self._current.next
self._current = self.head # Reset the current pointer
You don't have to implement next()
Update
Here is an example usage:
for data in myListIterator:
print data
# Without reset, the second time around won't work:
for data in myListIterator:
print data