Here is my code. I created a linked list manually to check if my method works or not. But the output I get is nothing. There is no output
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
node1=Node(2)
node2=Node(4)
node3=Node(5)
node1.next=node2
node2.next=node3
a=node1
class MyList():
def __init__(self):
self.head=Node()
def isEmpty(self,a):
return self.head.next is None
hello=MyList()
print(hello.isEmpty(a))
In case you want to add data to LinkedList, you need to set the head of the list manually.
This code is probably what you want:
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
node1=Node(2)
node2=Node(4)
node3=Node(5)
node1.next=node2
node2.next=node3
class MyList():
def __init__(self):
self.head=Node()
def isEmpty(self):
return self.head.data is None
hello=MyList()
print(hello.isEmpty())
new_hello = MyList()
new_hello.head=node1
print(new_hello.isEmpty())
Output
True
False
You never set the head node to point to another node in the way you're currently doing it (your head and "a" aren't actually the same node here). Pass in another variable as a node object to change this.
a = node1
class MyList():
def __init__(self, head):
self.head = head
def isEmpty(self):
return self.head is None # a linked list with a head is technically not empty
new_hello = MyList(a)
print (new_hello.isEmpty())
personally I would add an add_node(self, value) method and keep track of the end node as well, instead of doing it the way you are
Related
I'm trying to understand python and OOP along with data structures
I'm now looking at the implementation of a binary search tree
here is the class for the node structure
class Node():
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
the developer of this code has created the insert feature in Node class and in another class called tree
here is what it looks like in the node class :
def insert(self, data):
if self.data == data:
return False
elif data < self.data:
if self.leftChild:
return self.leftChild.insert(data)
else:
self.leftChild = Node(data)
return True
else:
if self.rightChild:
return self.rightChild.insert(data)
else:
self.rightChild = Node(data)
return True
however, he created a function with the same name in the tree class which looks like this
class Tree():
def __init__(self):
self.root = None
def insert(self, data):
if self.root:
return self.root.insert(data)
else:
self.root = Node(data)
return True
I do have some questions at this point, why are there 2 functions with the same name? and when I try to execute one of them without the other on this code it shows an error
if __name__ == '__main__':
tree = Tree()
tree.insert(10)
why does he made instance for tree not for node ?
can someone please explain those concepts for me, thanks!
When you creating tree object it doesn't creating any node. It's just defining a root variable with None. Node is creating when you call tree.insert() method.
insert() method in Tree class is checking if root is None it creating a new Node. Otherwise it calling the insert method in Node class.
Why does he made instance for tree not for node ?
Because insert() method in Node class only handles the case where tree has atleast one node or tree is not empty. That's why he creating the instance of Tree.
Code with insert() method in Tree class:
class Node():
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
class Tree():
def __init__(self):
self.root = None
def insert(self, root, data):
if root is None:
self.root = Node(data)
elif root.data < data:
if root.rightChild is None:
root.rightChild = Node(data)
else:
self.insert(root.rightChild, data)
else:
if root.leftChild is None:
root.leftChild = Node(data)
else:
self.insert(root.leftChild, data)
What is the difference between these constructors for a LinkedList, why is one better or worse than the other?
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Singly_Linked_List:
def __init__(self):
self.head = None
versus:
class Singly_Linked_List:
def __init__(self):
self.head = Node(0)
Does this affect how the SLL or DLL would be implemented for the addAtIndex, removeAtIndex functions for example?
I have a LinkedList class that has close to 200 lines of code. I would like to make a new class LLCircular(LinkedList) by always making sure that any myLL.tail.next is myLL.head. I believe I would need to update append(), push(), remove(), etc. accordingly. Is there a way I can do this to keep the original LinkedList class intact? Maybe a decorator or some dunder method?
For brevity's sake, if reading the code, my push() method is just the inverse of append(). I also have a pop() and remove() method, which would need to be updated, if I just rewrite those methods. As I am trying to avoid that approach, I am not posting that part of the code.
class LinkedListNode:
def __init__(self, value, nextNode=None, prevNode=None):
self.value = value
self.next = nextNode
self.prev = prevNode
def __str__(self):
return str(self.value)
class LinkedList:
def __init__(self, values=None):
self.head = None
self.tail = None
if values is not None:
self.append(values)
def __str__(self):
values = [str(x) for x in self]
return ' -> '.join(values)
def append(self, value=None):
if value is None:
raise ValueError('ERROR: LinkedList.py: append() `value` PARAMETER MISSING')
if isinstance(value, list):
for v in value:
self.append(v)
return
elif self.head is None:
self.head = LinkedListNode(value)
self.tail = self.head
else:
''' We have existing nodes '''
''' Head.next is same '''
''' Tail is new node '''
self.tail.next = LinkedListNode(value, None, self.tail)
self.tail = self.tail.next
if self.head.next is None:
self.head.next = self.tail.prev
return self.tail
'''class LLCircular(LinkedList):'''
''' ??? '''
Test Code:
foo = LinkedList([1,2,3])
foo.tail.next = foo.head #My LL is now circular
cur = foo.head
i = 0
while cur:
print(cur)
cur = cur.next
i +=1
if i>9:
break
What you want is to call your LinkedList base class functions using the super keyword, and then add the slight modifications to the LLCircular class function, i.e:
class LLCircular(LinkedList):
def append(self, value=None):
super(LLCircular, self).append(value)
# In addition to having called the LinkedList append, now you want
# to make sure the tail is pointing at the head
self.tail.next = self.head
self.head.prev = self.tail
If it is "circular" it won't need a tail or head, would it?
Nor "append" makes sense - insert_after and insert_before methods should be enough - also, any node is a reference to the complete circular list, no need for different objects:
class Circular:
def __init__(self, value=None):
self.value = value
self.next = self
self.previous = self
def insert_after(self, value):
node = Circular(value)
node.next = self.next
node.previous = self
self.next.previous = node
self.next = node
def insert_before(self, value):
node = Circular(value)
node.next = self
node.previous = self.previous
self.previous.next = node
self.previous = node
def del_next(self):
self.next = self.next.next
self.next.previous = self
def __iter__(self):
cursor = self.next
yield self
while cursor != self:
yield cursor
cursor = cursor.next
def __len__(self):
return sum(1 for _ in self)
I have got stack with a linked list. When I call list.push() it works fine, but it does nothing when I do the same in funtion init(). What could be the problem?
class Node:
def __init__(self, data):
self.data = data
self.nextNode = None
def __str__(self):
return str(self.data)
class linkedList:
def __init__(self):
self.head = None
self.end = None
def isEmpty(self):
return self.head == None
def push(self, item):
new_node = Node(item)
if not self.head:
self.head = self.end = new_node
else:
new_node.nextNode = self.head
self.head = new_node
#doesnt work
def init():
list = linkedList()
list.push("a")
init()
print(list.isEmpty()) #True
#works
list = linkedList()
list.push("a")
print(list.isEmpty()) #False
Outside a function, you cannot access a local object you create inside function. Returning it makes it available:
def make_list():
my_list = linkedList()
my_list.push("a")
return my_list
my_list = make_list()
print(my_list.isEmpty())
Don't use the name list for your objects as it shadows the builtin list.
You need to RETURN the object you make within the function, because that object 'dies' when function ends, so there is no object there for you to look into. That's why you get empty true.
here is how you make it work:
def make():
aList = linkedList()
aList.push("a")
return aList
then you would store whatever is return from that object:
some_list = make() # storing the linkedlist that make() returns into
# variable called 'some_list'
print(some_list.isEmpty()) # True
I have the following Linked List implementation. There is a problem with the printlist() function. The while loop is turning an error that there is no attribute next for self. Is there a better way to write this function? Thank you!!!
class Node:
def __init__(self, data, next=None):
self.data=data
def _insert(self, data):
self.next=Node(data)
def _find(self, data):
if self.data==data:
return self
if self.next is None:
return None
while self.next is not None:
if self.next.data==data:
return self.next
return None
def _delete(self, data):
if self.next.data == data:
temp=self.next
self.next =self.next.next
temp=None
def _printtree(self):
while self:
print self.data,
self=self.next
class LinkedList:
def __init__(self):
self.head=None
def insert(self, data):
if self.head:
self.head._insert(data)
else:
self.head=Node(data)
def find(self, data):
if self.head.data==data:
return self.head
return self.head._find(data)
def delete(self, data):
if self.head.data==data:
head=None
return
self.head._delete(data)
def printtree(self):
self.head._printtree()
add next attribute to Node's ini method
you should define printtree of LinkedList this way:
def printree(self):
current_node = self.head
print current_node.data
while current_node.next is not None:
print current_node.next.data
current_node = current_node.next
adding a repr method will make your code nicer