Python class basics functions not working - python

Why the binary tree is not getting inverted in this class?
class Node:
def __init__(self, data):
self.left = None
self.right= None
self.data = data
def show_tree (self):
if self.left:
self.left.show_tree()
print(self.data)
if self.right:
self.right.show_tree()
class Operation:
def invertTree(self,root):
if root:
root.left, root.right==root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
root = Node(10)
b=Node(15)
c=Node(19)
d=Node(5)
e=Node(59)
d.left=e
d.right=c
root.left=b
root.right=d
root.show_tree()
oper=Operation()
inver =oper.invertTree(root)
inver.show_tree()
The other class is returning the inverted root so finally it should return the inverted root to inver but when I display it, it shows same tree

root.left, root.right==root.right, root.left compares the values and returns a boolean, if you want to assign you need to use a single = operator

Related

I do not understand why my method for adding nodes into binary tree does not work?

I am trying to learn Python better, and I know one can easily find the solution for adding items into BTS, but I do not understand why my implementation of add method does not work? Can someone please help?
class Node:
def __init__(self, data, left = None, right = None):
self.data = data
self.left = left
self.right = right
class Tree:
def __init__(self):
self.root = None
def add(self, data):
self.root = self._add(data,self.root)
# if I change this line with just "self._add(data,self.root)" it would not iterate tree at all..
def _add(self,data,root):
if root is None:
root = Node(data)
return root
elif data <= root.data:
root.left = self._add(data, root.left)
else:
root.right = self._add(data,root.right)
def in_order(self):
if self.root is not None:
self._in_order(self.root)
def _in_order(self, root):
if root is not None:
self._in_order(root.left)
print(str(root.data) + ' ')
self._in_order(root.right)
I am printing in classical in-order fashion. My question is after inserting a few numbers, why do I still get the result for a root node to be None ?
This kind of implementation worked for me before in C or in Java, but in Python it does not work.
EDIT: I added my in-order method.
I have also tried this but it also does not work:
def add(self,data):
if self.root == None:
self.root = Node(data)
elif data <= self.root.data:
self.root.left = self.add(self.root.left,data)
else:
self.root.right = self.add(self.root.right,data)
I get a TypeError: add() takes 2 positional arguments but 3 were given
My question is after inserting a few numbers, why do I still get the result for a root node to be None ?
With this following line, you're setting self.root to be the return value of the method _add. Since this method has no return statement, it returns None by default.
self.root = self._add(data,self.root)
I get a TypeError: add() takes 2 positional arguments but 3 were given
In this case, you're calling self.add(self.root.left,data) with three parameters: the implicit self reference, self.root.left and data.
However, the method declaration receives only the parameters self and data.

Problem with the print of a python tree data structure [duplicate]

This question already has answers here:
Python prints None
(2 answers)
Closed 3 years ago.
When I run this program in m_tree.print_values(root) appears the data and 3 times None to any Node present in this tree. I don't understand why appears these None because the function should print only the value.
class Tree:
def __init__(self, root=None):
self.root = root
def print_values(self, root):
if root != None:
print(root.data)
print(self.print_values(root.left))
print(self.print_values(root.right))
#Define other tree operations that you want to perform here
class Node:
def __init__(self, data=0, left=None, right=None):
self.data = data
self.left=left
self.right=right
#Create a root node
root = Node(0)
#Create a tree with the root node
m_tree = Tree(root)
#Add a left and right node to the root
left_node = Node(3)
right_node = Node(4)
root.left = left_node
root.right = right_node
m_tree.print_values(root)
print_values has no return statement, so it returns None by default. So if you call print_values and print the result, it will print None.
Change your recursive calls so that they call print_values without printing the result.
def print_values(self, root):
if root != None:
print(root.data)
self.print_values(root.left)
self.print_values(root.right)
You're calling
print(self.print_values(root.left))
The self.print_values function prints the values, and then returns None. So first you get the value printed by print_values, and then you print(None) because that's what self.print_values returned.

Would this function for checking if a BST(Binary Search Tree ) Is valid work Python

So this is my code below, my thought process is that if the smallest value in the tree is less than the root and the largest value in the tree is greater than the root it should check if the BST is valid
def min(self):
while self.left:
self.root = self.left
return self.root
def max(self):
while self.right:
self.root = self.right
return self.value
def valid(self):
min = min(self.left)
max = max(self.right)
if self.root > min and self.root < max:
return True
Don't reuse the names min and max. They already refer to built-in functions.
Your min and max functions change the tree, by changing self.root.
You should be validating that the values of the left and right child nodes are correct relative to the parent node, then validating that each of the BSTs rooted at those child nodes is itself valid.
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def valid(self):
if self.left and self.left.value > self.value:
return False
if self.right and self.right.value < self.value:
return False
return all(node.valid() for node in (self.left, self.right) if node)

Recursive function failing while inorder traverse in tree ds

I am trying to implement tree data structure but I am stuck and having trouble understanding how to create a recursive function for inorder traversal for my binary tree.
This is what i have done so far:
class Node:
def __init__(self, node):
self.node = node
self.left = None
self.right= None
def inorder_traversal(self):
if self.node != None:
return inorder_traversal(self.node.left)
return self.node
return inorder_traversal(self.node.right)
I don't seem to understand what's wrong.
Test inputs:
root = Node(1)
root.left = Node(3)
root.right = Node(4)
Error:
File "trees-implementation.py", line 23, in inorder_traversal
return inorder_traversal(self.node.left)
NameError: name 'inorder_traversal' is not defined
It looks like you've defined your traversal functions with respect to the Node. Does this make sense to you?
You should define a traversal with respect to the Tree, not the Node. The Node does not know it belongs to the tree, it's a dumb object.
Define the node.
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right= None
Define the tree. Also define your traversal methods here.
class Tree:
def __init__(self, root=None):
self.root = root
def inorder_traversal(self):
def _inorder(root):
if root != None:
yield from _inorder(root.left)
yield root.value
yield from _inorder(root.right)
return list(_inorder(self.root))
Initialise the tree with a root, and then traverse it.
tree = Tree(root)
tree.inorder_traversal()
[3, 1, 4]
First, could you check if when you have your object, you don't put a parameter in
root = Node()
Then are you sure you can have several returns in your inorder_traversal() function ?
Finally, the function is in the class Node() so if you call it try to add self.yourfunction

Binary Search Tree operations

I am trying to implement Binary Search Tree operations in python. As of now, I have written some code to add nodes to this search tree (sorted).
Here's what I've in my code:
class TreeNode:
def __init__(self, data):
self.data = data
self.lLink = None
self.rLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data):
if self.root is None:
self.root = TreeNode(data)
else:
if data < self.root.data:
if self.root.lLink is None:
self.root.lLink = TreeNode(data)
else:
AddNode(self.root.lLink, data)
else:
if self.root.rLink is None:
self.root.rLink = TreeNode(data)
else:
AddNode(self.root.rLink, data)
def InOrder(self, head):
if self.root.lLink is not None:
InOrder(self.root.lLink)
print self.root.data,
if self.root.rLink is not None:
InOrder(self.root.rLink)
myTree = BinaryTree()
myTree.AddNode(15)
myTree.AddNode(18)
myTree.AddNode(14)
How do I test if my AddNode() method is correct? I know the algorithm but just to be sure.
What I was thinking of is to create an InOrder() method and try to print elements through this InOrder traversal. As a result, my data added to the tree should be displayed in sorted order. If it is displayed in sorted order, I'll be sure that both my AddNode() and InOrder() methods are correct.
Your BinaryTree class is faulty, changing the order of insertions to
myTree.AddNode(14)
myTree.AddNode(18)
myTree.AddNode(15)
raises an error - NameError: global name 'AddNode' is not defined.
This is because in the lines, AddNode(self.root.rLink, data) and AddNode(self.root.lLink, data) you seem to be calling the AddNode function on instances of TreeNode which is not possible. I fixed up some of the errors in your code and it should work great now.
class TreeNode:
def __init__(self, data):
self.data = data
self.lLink = None
self.rLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data):
if self.root is None:
self.root = TreeNode(data)
else:
self.AddHelper(data, self.root)
def AddHelper(self, data, startingPoint):
if data < startingPoint.data:
if startingPoint.lLink is None:
startingPoint.lLink = TreeNode(data)
else:
self.AddHelper(data, startingPoint.lLink)
else:
if startingPoint.rLink is None:
startingPoint.rLink = TreeNode(data)
else:
self.AddHelper(data, startingPoint.rLink)
def InOrder(self):
self.InOrderHelper(self.root)
def InOrderHelper(self, startingPoint):
if startingPoint is None:
return
self.InOrderHelper(startingPoint.lLink)
print startingPoint.data,
self.InOrderHelper(startingPoint.rLink)
Output Test :
>>> myTree = BinaryTree()
>>> myTree.AddNode(14)
>>> myTree.AddNode(18)
>>> myTree.AddNode(15)
>>> myTree.InOrder()
14 15 18
Inserting can be a little tricky, especially because the function is a part of the tree itself. So, you call the insert function on the tree, but specifying a starting point. This defaults to root, so you can leave the argument when you call the function.
Also, I think you are a little unclear about how self works in a function. You cannot pass it as an argument to the function, which is what it seems you have done.
class TreeNode:
def __init__(self, data):
self.data = data
self.rLink = None
self.lLink = None
class BinaryTree:
def __init__(self):
self.root = None
def AddNode(self, data, node=None):
if not node :
node = self.root
if self.root is None:
self.root = TreeNode(data)
else:
if data < node.data:
if node.lLink is None:
node.lLink = TreeNode(data)
else:
self.AddNode(data, self.root.lLink)
else:
if node.rLink is None:
node.rLink = TreeNode(data)
else:
self.AddNode(data, self.root.rLink)
def InOrder(self, head):
if head.lLink is not None:
self.InOrder(head.lLink)
print head.data,
if head.rLink is not None:
self.InOrder(head.rLink)
myTree = BinaryTree()
myTree.AddNode(14)
myTree.AddNode(15)
myTree.AddNode(18)
myTree.InOrder(myTree.root)
Testing the insert function with an in-order traversal is the best approach.
This should work. You are not going down the tree if you use self.root.lLink every time.
Optionally, you could write one more line of code to check if the output is indeed in ascending order.

Categories

Resources