I am writing this code below but when I am trying to call the function size() it is throwing error
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
def insert(self,data):
if self.data:
if data<self.data:
if self.left is None:
self.left=Node(data)
else:
self.left.insert(data)
else:
if self.right is None:
self.right=Node(data)
else:
self.right.insert(data)
else:
self.data=data
def size(node):
if node is None:
return 0
else:
return (size(node.left)+ 1 + size(node.right))
root=Node(4)
root.insert(5)
root.insert(3)
root.insert(8)
print(size(root))
The error below is getting thrown:
NameError Traceback (most recent call last)
<ipython-input-7-8c72ba7719dc> in <module>
41 root.insert(8)
42
---> 43 print(size(root))
44
45 #root.print()
NameError: name 'size' is not defined
Either define size after the class statement:
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
def insert(self,data):
...
def size(node):
if node is None:
return 0
else:
return (size(node.left)+ 1 + size(node.right))
or make it a proper method:
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
def insert(self,data):
...
def size(self):
rv = 1
if self.left is not None:
rv += self.left.size()
if self.right is not None:
rv += self.right.size()
return rv
In your Code, size is a method bound to a Node object, so you need to call root.size() (because root is a Node instance)
After some discussion with #ShadowRanger, here is what I came up with.
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
#dataclass
class Node:
data: Any
left: Node = None
right: Node = None
def insert(self, data: Any) -> None:
if self.data:
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
else:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
def num_child_nodes(self) -> int:
num_nodes = 0
if self.left:
num_nodes += 1 + self.left.num_child_nodes()
if self.right:
num_nodes += 1 + self.right.num_child_nodes()
return num_nodes
Related
This question already has answers here:
I'm getting an IndentationError. How do I fix it?
(6 answers)
Closed 5 months ago.
I am trying to figure out how to write code for binary trees in python and this error keeps coming that a certain function is not defined.
class Node:
def __init__(self , value):
self.v = value
self.right = None
self.left = None
def insert(self , value):
if self.value:
if value < self.value:
if self.left is None:
self.left = Node(value)
else:
self.left.insert(value)
elif value > self.value:
if self.right is None:
self.right = Node(value)
else:
self.right.insert(value)
else:
self.value = value
# def in_order_traversal(self):
# def print(self):
# self.in_order_traversal()
if __name__ == '__main__':
r = Node
the error this code gives me is
"name 'Node' is not defined"
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [16], in <cell line: 1>()
----> 1 class Node:
2 def __init__(self , value):
3 self.v = value
Input In [16], in Node()
21 # def in_order_traversal(self):
22
23 # def print(self):
24 # self.in_order_traversal()
25 if __name__ == '__main__':
---> 26 r = Node
NameError: name 'Node' is not defined
what is wrong? what do I need to do?
R = Node is not valid , use r = Node(value)
The first mistake you were doing was Node calling without value as it required 1 arguments. 2nd mistake is in assigning the value in Node to self.v while in condition you are always pointing this value with self.value
class Node:
def __init__(self , value):
self.value = value
self.right = None
self.left = None
def insert(self , value):
if self.value:
if value < self.value:
if self.left is None:
self.left = Node(value)
else:
self.left.insert(value)
elif value > self.value:
if self.right is None:
self.right = Node(value)
else:
self.right.insert(value)
else:
self.value = value
# def in_order_traversal(self):
# def print(self):
# self.in_order_traversal()
if __name__ == '__main__':
r = Node(50)
# r.Node(50)
r.insert(30)
r.insert(20)
Being a beginner, I have been trying to implement Binary Tree in python. And have been available to implement a lot successfully with only one problem that I am unable to return a list of all the elements (traverse())in the binary tree. I am using two classes here, Node and BinaryTree.
Node Class
class Node:
def __init__(self, val):
self.value = val
self.left = None
self.right = None
Traverse method to return all the elements in the binary tree.
def traverse(self): #<-- Problem here
tree_elements = []
if self.left != None:
self.left.traverse()
tree_elements.append(self.value)
#debug
print(self.value, end=" ")
if self.right != None:
self.right.traverse()
return tree_elements
def addNode(self, node):
if node.value < self.value and node.value != self.value:
if self.left == None:
self.left = node
else:
self.left.addNode(node)
elif node.value > self.value and node.value != self.value:
if self.right == None:
self.right = node
else:
self.right.addNode(node)
def search(self, val):
if val == self.value:
return "Found"
elif val < self.value:
if self.left != None:
return self.left.search(val)
else:
return "Not Found "
elif val > self.value:
if self.right != None:
return self.right.search(val)
else:
return "Not Found"
Binary Tree
class BinaryTree:
def __init__(self):
self.root = None
def addVlaue(self, val):
node = Node(val)
if self.root == None:
self.root = node
else:
self.root.addNode(node)
def search(self, val):
if self.root == None:
return False
else:
return self.root.search(val)
def traverse(self):
if self.root == None:
return "no data"
else:
return self.root.traverse()
Problem:
traverse method has to return all the elements in the binary tree, but i have been getting only first value of the tree.
example:
elements: 100 18 46 5 65 5 31 71 94 43 #input in the tree
output from tree:
5 18 31 43 46 65 71 94 100 #expected output
[100] #output from the tree
The tree_elements list needs to go along the recurvise calls, collecting each node along the way. In other words, it must be passed as an argument to traverse calls (except when calling traverse for the root node).
Otherwise a new list is created and discarded in each traverse call (since you never do anything with the return value of traverse during its recursion), except for the top recursive call which returns the root element only.
Try this implementation:
def traverse(self, tree_elements=None):
if tree_elements is None:
tree_elements = []
if self.left != None:
self.left.traverse(tree_elements=tree_elements)
tree_elements.append(self.value)
if self.right != None:
self.right.traverse(tree_elements=tree_elements)
return tree_elements
I have recently started learning and Implementing some data structures in Python and was trying Binary Search tree and completed the code.
Everything is running fine except the deletion of root node.
I have divided my code into 3 modules
Here is my Code :
Node.py
class Node:
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
def insert(self, data):
if data < self.data:
if not self.leftChild:
self.leftChild = Node(data)
else:
self.leftChild.insert(data)
else:
if not self.rightChild:
self.rightChild = Node(data)
else:
self.rightChild.insert(data)
def remove(self, data, parentNode):
if data < self.data:
if self.leftChild is not None:
self.leftChild.remove(data, self)
elif data > self.data:
if self.rightChild is not None:
self.rightChild.remove(data, self)
else:
if self.leftChild is not None and self.rightChild is not None:
self.data = self.rightChild.getMin()
self.rightChild.remove(self.data, self)
elif parentNode.leftChild == self:
if self.leftChild is not None:
tempNode = self.leftChild
else:
tempNode = self.rightChild
parentNode.leftChild = tempNode
elif parentNode.rightChild == self:
if self.leftChild is not None:
tempNode = self.leftChild
else:
tempNode = self.rightChild
parentNode.rightChild = tempNode
def getMin(self):
if self.leftChild is None:
return self.data
else:
self.leftChild.getMin()
def getMax(self):
if self.rightChild is None:
return self.data
else:
self.rightChild.getMax()
def traverseInOrder(self):
if self.leftChild is not None:
self.leftChild.traverseInOrder()
print(self.data)
if self.rightChild is not None:
self.rightChild.traverseInOrder()
BinarySearchTree.py
from BinarySearchTrees.Node import Node
class BST:
def __init__(self):
self.rootNode = None;
def insert(self, data):
if self.rootNode is None:
self.rootNode = Node(data)
else:
self.rootNode.insert(data)
def removal(self, dataToRemove):
if self.rootNode:
if self.rootNode.data == dataToRemove:
tempNode = Node(None)
tempNode.leftChild = self.rootNode
print("The value of dataToRemove : " + str(dataToRemove))
self.rootNode.remove(dataToRemove, tempNode)
else:
self.rootNode.remove(dataToRemove, None)
def getMin(self):
if self.rootNode:
return self.rootNode.getMin()
def getMax(self):
if self.rootNode:
return self.rootNode.getMax()
def traverseInOrder(self):
if self.rootNode:
self.rootNode.traverseInOrder()
Output.py
from BinarySearchTrees.BinarySearchTree import BST
bst = BST()
bst.insert(5)
bst.insert(8)
bst.insert(3)
bst.insert(7)
bst.insert(9)
bst.insert(4)
bst.insert(2)
bst.traverseInOrder()
bst.removal(5)
bst.traverseInOrder()
and the Error with the Removal command is :
Traceback (most recent call last):
File "G:\Docs\Liclipse Projects\DS\BinarySearchTrees\Output.py", line 16, in <module>
bst.removal(5)
File "G:\Docs\Liclipse Projects\DS\BinarySearchTrees\BinarySearchTree.py", line 24, in removal
self.rootNode.remove(dataToRemove, tempNode)
File "G:\Docs\Liclipse Projects\DS\BinarySearchTrees\Node.py", line 34, in remove
self.rightChild.remove(self.data, self)
File "G:\Docs\Liclipse Projects\DS\BinarySearchTrees\Node.py", line 23, in remove
if data < self.data:
TypeError: '<' not supported between instances of 'NoneType' and 'int'
It's like the data parameter passed in remove function in Node is returning a None value despite of giving a value in the BinarySearchTree removal function.
If anyone could find the error in my code please tell me the solution. It would be a great help..
Both instances of if data < self.data: should be : if data is not None and (data < self.data):
This will short circuit the check when data is not None
This is my node:
class Node(object):
def __init__(self, data, next = None):
self.data = data
self.next_node = next
def get_next(self):
return self.next_node
def set_next(self, next):
self.next_node = next
def get_data(self):
return self.data
def set_data(self):
self.data = data
And this is the LinkedList itself:
class LinkedList(object):
def __init__(self, root = None):
self.root = root
self.size = 0
def size(self):
return self.size
def insert(self, data):
new_node = Node (data, self.root)
self.root = new_node
self.size += 1
def delete(self, data):
this_node = self.root
prev_node = None
while this_node:
if this_node.get_data() == data:
if prev_node:
prev_node.set_next(this_node.get_next())
else:
self.root = this_node
self.size -= 1
return True
else:
prev_node = this_node
this_node = this_node.get_next()
return False
def search(self, data):
this_node = self.root
while this_node:
if this_node.get_data() == data:
return data
else:
self.root = this_node.get_next()
return None
def printLL(self):
this_node = self.root
while this_node:
print(this_node.data)
this_node = this_node.get_next()
Finally, these are the tests I'm performing:
ll = LinkedList()
ll.insert(1)
ll.insert(2)
ll.printLL()
ll.delete(2)
ll.printLL()
if ll.search(2):
print("Value 2 found")
else:
print("Value 2 not found")
if ll.search(1):
print("Value 1 found")
else:
print("Value 1 not found")
ll.insert(4)
ll.printLL()
print(str(ll.size()))
I am currently getting this output:
2
1
2
1
Value 2 found
Value 1 not found
4
1
Traceback (most recent call last):
File "C:\Users\ErikIngvoldsen\Documents\Python Code\TestCode.py", line 71, in <module>
print(str(ll.size()))
TypeError: 'int' object is not callable
Why is the object not callable? Also, why isn't my delete function working? For reference, this is what my output SHOULD look like:
2 1
1
Value 2 not found
Value 1 found
4 1
2
There's also the formatting problem, but for now I'll just focus on getting this to work properly.
size is a instance variable not a method of the linkedlist class. You cannot call a variable.That is the error. instead of doing print(str(ll.size())), do print(str(ll.size))
I'm making a binary tree in Python 3.5.0 and I'm making the insert function for it. But I'm running in a bit of a problem when I call tree_insert inside itself it gives me this error:
File "D:/MadeUpPath/BinaryTree.py", line 10, in tree_insert
tree_insert(data, self.left)
NameError: name 'tree_insert' is not defined
class BinaryTree():
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def tree_insert(self, data):
if (data < self.data):
if (self.left != None):
tree_insert(data, self.left)
else:
self.left = BinaryTree(data)
else:
if (self.right != None):
tree_insert(data, self.right)
else:
self.right = BinaryTree(data)
Upon testing further I found out that recursive functions simply don't work. I tried the following code to be sure but gave me the same error:
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
File "D:/MadeUpPath/BinaryTree.py", line 23, in factorial
return n * factorial(n - 1)
NameError: name 'factorial' is not defined
If anyone can point me in the right direction it would be much appreciated :)
tree_insert() is an instance method, call it via self.tree_insert():
class BinaryTree():
def __init__(self, data):
self.left = None
self.right = None
self.data = data
def tree_insert(self, data):
if (data < self.data):
if (self.left != None):
self.tree_insert(data, self.left)
else:
self.left = BinaryTree(data)
else:
if (self.right != None):
self.tree_insert(data, self.right)
else:
self.right = BinaryTree(data)