I have done the following linked list in python, it works fine, but I was wondering if there is another way to to the part add_item to a linked list. In that part what I want to do is to keep a pointer in the first element, and so adding the elements in front of it, for example:
1
first
1----->2
first
1----->2----->3
first
my code is:
class Node:
def __init__(self,elem=None,next=None):
self.elem=elem
self.next=next
def __repr__(self):
return 'Node(elem={}, next={})'.format(self.elem, self.next)
class LinkedList:
def __init__(self):
self.size=0
self.first=None
self.linkedlist=Node()
def add(self,elem):
node=Node(elem)
if self.size==0:
self.first=node
else:
self.linkedlist.next=node
self.linkedlist=node
self.size=self.size+1
is there another way to perform this behaviour wihout using the auxiliar self.linkedlist that I have in the builder of the LinkedList class?
Thanks
Keep track of last element and always a new node to its next. Then update the last
class Node:
def __init__(self, elem=None, next=None):
self.elem = elem
self.next = next
class LinkedList:
def __init__(self):
self.size = 0
self.first = None
self.last = None
def add(self, elem):
node = Node(elem)
if self.size == 0:
self.first = node
self.first.next = node
self.last = node
else:
self.last.next = node
self.last = node
self.size += 1
I think that something like the following method would work:
class LinkedList:
# what you have so far
def add_to_front(self, elem):
if self.size == 0:
self.add(elem)
else:
node = Node(elem, self.first)
self.first = node
self.size += 1
You currently have a reference to the head of the list in self.first and a reference to the current tail in self.linkedlist. That allows efficient additions at either point.
ll = LinkedList()
for i in xrange(3):
ll.add_to_front(i)
>>> ll.linkedlist
Node(elem=0, next=None)
>>> ll.first
Node(elem=2, next=Node(elem=1, next=Node(elem=0, next=None)))
>>> ll.add('x')
>>> ll.linkedlist
Node(elem=x, next=None)
>>> ll.first
Node(elem=2, next=Node(elem=1, next=Node(elem=0, next=Node(elem=x, next=None))))
>>>
Try this(I've changed the add method only. This doesn't involve the linkedlist class member.) -
class LinkedList:
def __init__(self):
self.size=0
self.first=None
def add(self,elem):
if self.size == 0:
self.first = Node(elem)
else:
self.first = Node(elem, self.first)
self.size += 1
Related
the add method() only prints just two value, I want to print all the number what I added. size does work well but I do not know why value does not work when i want to print all the value
enter code here
class Node():
def __init__(self,value):
self.next =None
self.val =value
class single_linked_list():
def __init__(self):
self.head =None
self.size =0
def add(self,val):
node =Node(val)
if self.head is None:
self.head =node
self.size +=1
else:
self.head.next =node
self.size +=1
def __str__(self):
vals =[]
node =self.head
while node is not None:
vals.append(node.val)
node =node.next
return f"[{','.join(str(val)for val in vals)}]"
sl=single_linked_list()
sl.add(3)
sl.add(5)
sl.add(50)
sl.add(9)
print(sl)
print(sl.size)
# it just show these value :[3,9]
#4 as size fine
Problem
The problem is that you are covering only 2 cases in the add() method:
There are ZERO nodes in the list.
There is only ONE node in the list
What about the case when there is more than 1 node in the list?
Let's assume there are two nodes in the list: 1 -> 2
Now, to add 3 in the list, the add() method will check if the head is None. Which is not the case because there are 2 elements.
Then, it will simply add 3 as the next of head. Which was actually set to 2 before. Therefore, 2 is lost and the new list is 1 -> 3
Solution
To solve this issue, you have to edit the add() function and check if there is more than 1 node in your list. It can be done like this:
def add(self,val):
node = Node(val)
if self.head is None:
self.head = node
self.size += 1
else:
curr_node = self.head
# Go to the last element of the list
while curr_node.next:
curr_node = curr_node.next
# Add new element after the last element
curr_node.next = node
self.size += 1
That is because your add method is not really adding nodes to the list, it is just replacing the head.next value. So you have at most 2 nodes in the list with new values just replacing the second position.
Here's the fixed code for add method:
def add(self,val):
node =Node(val)
if self.head is None:
self.head =node
self.size +=1
else:
currentNode = self.head
while currentNode.next:
currentNode = currentNode.next
currentNode.next = node
self.size += 1
Here's a Repl.it link, if you want to see the output - https://repl.it/repls/RewardingVengefulTask
class Node():
def __init__(self,value):
self.next =None
self.val =value
class single_linked_list():
def __init__(self):
self.head =None
self.size =0
def add(self,val):
node =Node(val)
if self.head is None:
self.head =node
self.size +=1
else:
self.head.next =node
self.size +=1
Assigned to design a linked list class from scratch using a generator to iterate through the list, but I've had a problem debugging this issue:
class LinkedList:
def __init__(self, data = None):
self.node = Node(data)
self.first = self.node
self.last = self.node
self.n = 1
def append(self, data = None):
new = Node(data)
self.last.next = new
self.last = new
self.n += 1
def __iter__(self):
self.index = self.first
return self.generator()
def generator(self):
for i in range(0, self.n):
yield self.index
self.index = self.index.next
One of the tests that the current generator passes is:
for n in a:
print n
# which should and does output
0
1
2
However, it fails to output the proper values in this case
for n in a:
if n == 2:
break
else:
print n
# Outputs 0 1 2, instead of:
0
1
I think my understanding of generators is lacking, and would love any help you guys have to offer!
Your shouldn't use n == 2 as the break-condition.
Try this:
# Assume your defined class `Node.py` like this:
class Node:
def __init__(self, data=None):
self.val = data
self.next = None
# I didn't modify your `LinkedList.py`
class LinkedList:
def __init__(self, data=None):
self.node = Node(data)
self.first = self.node
self.last = self.node
self.n = 1
def append(self, data=None):
new = Node(data)
self.last.next = new
self.last = new
self.n += 1
def __iter__(self):
self.index = self.first
return self.generator()
def generator(self):
for i in range(0, self.n):
yield self.index
self.index = self.index.next
if __name__ == '__main__':
ass = LinkedList(0)
ass.append(1)
ass.append(2)
ass.append(3)
for n in ass:
if n.val == 2: # Notice here
break
else:
print(n.val) # And here
I am trying to do an N-Ary tree based on Linked-Lists and Nodes. But whenever I try to add a new value to the tree I keep getting:
NameError: name 'self' is not defined
I work with modules so I have to import the classes from other files.
I get this error in def addTree(self, value, parent = self.root): on Tree Code
Tree Code
from Resources.LinkedList import *
class Tree:
def __init__(self):
self.root = LinkedList()
def addTree(self, value, parent = self.root):
parent.addLinkedList(value)
Node Code
from Resources.LinkedList import *
class Node:
def __init__(self,name):
self.name = name
self.children = LinkedList()
self.next = None
Linked-List Code
from Resources.Node import *
from Resources.Compare import *
class LinkedList:
def __init__(self):
self.first = None
def addLinkedList(self,value):
if (not self.first):
self.first = Node(value)
else:
compare = Compare()
if(compare.compare(self.first,value)>0):
stack = self.first
self.first = Node(value)
self.first.next = stack
return True
else:
previous = self.first
current = self.first.next
while(current):
if (compare.compare(current,value)<0):
previous = current
current = current.next
return True
elif (compare.compare(current,value)>0):
stack = current
previous.next = Node(value)
previous.next.next = stack
return True
else:
previous.next = Node(value)
previous.next.next = current.next
return True
previous.next = Node(value)
return True
Also thanks for your help, I'm kinda new to Python and I don't know what I am doing wrong.
The problem is that "self" is only defined within the method and cannot be used in the arguments, the trick in these cases is to use None as an argument and make the verification:
def addTree(self, value, parent = None):
if parent is None:
parent = self.root
parent.addLinkedList(value)
I'm trying to write a next method to be able to iterate over a linked list object with a for loop and no matter how I change my code I keep getting "'NoneType' object is not callable". It's an assignment and therefore I can't change anything when it comes to the other constructors and methods. Only thing I can play around with is iter and next. This is my code:
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self, fdata):
firstNode = Node(fdata)
self.first = firstNode
self.last = firstNode
self.n = 1
def append(self, ndata):
newNode = Node(ndata)
self.last.next = newNode
self.last = newNode
self.next = None
self.n += 1
def __iter__(self):
return self
def next(self):
if self.__current.next == None:
raise StopIteration
else:
self.__current = self.__current.next
return self.__current.next.ndata
a = LinkedList(0); a.append(1); a.append(2)
for n in a:
print n
Looks like you advance reading too far. Try:
self.__current = self.__current.next
return self.__current.data
Because self.__current.next at then moment will point to next-next element. And in case of list dnid - to nowhere.
I have worked with linked lists and classes almost exclusively in c++, so I am having trouble getting this to work. The first class is supposed to have the variables name and next, an init function, two getter functions, and two setter functions. The second class(Line) is supposed to have an init function and an add function that adds items to the end of the linked list. I can't seem to get my add function to work. Any help is appreciated.
This is the code I have so far.
class PersonList():
"""
The class to represent the node in a linked list of people. It takes the variables:
name, which represents the person's name, and next_person, which links the next
person in the linked list.
"""
def __init__(self, name = None, next_ = None):
self.__name = name
self.__next = next_
def getName(self):
return self.__name
def getNext(self):
return self.__next
def setName(self, new_name):
self.__name = new_name
def setNext(self, new_person):
self.__next = new_person
def __str__(self):
return (self.__name)
def printlist(node):
next_node = node.getNext()
while next_node != None:
next_node = node.getNext()
print (node)
node = node.getNext()
class Line():
""" The class that represents the line of people as the linked list. Takes the variable
head, that denotes the first person in the line
"""
def __init__(self, head = None):
self.head = None
def add(self, name):
if self.head == None:
self.head = PersonList(name)
else:
Or just keep track of the tail to avoid traversing the whole list each time you want to add something:
class Line():
""" The class that represents the line of people as the linked list. Takes the variable
head, that denotes the first person in the line
"""
def __init__(self, head = None):
self.head = None
self.tail = None
def add(self, name):
tmp = PersonList(name)
if self.head == None:
self.head = tmp
self.tail = tmp
else:
self.tail.next = tmp
self.tail = tmp
def add(self, name):
if self.head == None:
self.head = PersonList(name)
else:
tmp = self.head
while tmp._next is not None: #while we are not at the end of the line
tmp = tmp._next
#end of line
tmp._next = PersonList(name) #get in line at the end
is one option