Why is the following code throwing an error? - python

So, I am trying to define a function which would invert a binary tree, and when I run the below code, and then execute a_node.binInversion(), I get the error which says, "NameError: name 'binInversion' is not defined". Why is that error happening?
The code I'm executing is as below:
class BinaryTree:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def insert_left(self, value):
if self.left == None:
self.left = BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.left = self.left
self.left = new_node
def insert_right(self, value):
if self.right == None:
self.right = BinaryTree(value)
else:
new_node = BinaryTree(value)
new_node.right = self.right
self.right = new_node
def binInversion(self):
if self.left is None and self.right is None:
return 0
else:
binInversion(self.left)
binInversion(self.right)
self.left, self.right = self.right, self.left
a_node = BinaryTree('a')
a_node.insert_left('b')
a_node.insert_right('c')
b_node = a_node.left
b_node.insert_right('d')
c_node = a_node.right
c_node.insert_left('e')
c_node.insert_right('f')
d_node = b_node.right
e_node = c_node.left
f_node = c_node.right
a_node.binInversion()
Also, I know that there are high chances of binInversion() function not working as expected. Please DO NOT disclose the solution for inverting a binary tree, as I want to give it a shot on my own before looking at the solution.

a few bugs here:
binInversion is not a function, it is a class method, remember to call self.binInversion() instead of binInversion()
after the above fix, there will still be an error that says something along the lines of binInversion was given too many arguments. Your method of binInversion takes no arguments, try something like def binInversion(self, node) to pass in another argument or node.

Related

How do I return the children of recursive nodes in a python binary tree?

I currently have my code set up so I have a class that creates the first node of a binary search tree. Then, using a create_node method, I can add whatever node. How can I return the children of each created note?
When I run the following, I get an output of "Left child: None Right Child: None" when it should be "Left child: 3 Right Child: 7"
I'd assume it has something to do with the dictionary not being updated? If this is the case, how can I continually update it? Thank you!
totaldict = {}
class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def search(self, value):
if value < self.data:
if self.left == None:
return False
else:
return self.left.search(value)
elif value > self.data:
if self.right == None:
return False
else:
return self.right.search(value)
else:
return True
def create_node(self, value):
if value < self.data:
if self.left == None:
self.left = TreeNode(value)
totaldict[value] = TreeNode(value)
else:
return self.left.create_node(value)
elif value > self.data:
if self.right == None:
self.right = TreeNode(value)
totaldict[value] = TreeNode(value)
else:
return self.right.create_node(value)
else:
print("Node already exists")
def pos_child(self, value):
if self.search(value):
if value in totaldict:
return "Left child: " + str(totaldict[value].left) + " Right Child: " + str(totaldict[value].right)
else:
print("Node does not exist, use create_node method")
root = TreeNode(10)
root.create_node(5)
root.create_node(15)
root.create_node(3)
root.create_node(7)
print(root.pos_child(5))
The problem is here:
if self.right == None:
self.right = TreeNode(value)
totaldict[value] = TreeNode(value) # HERE
You create new TreeNode but it's not connected at all to root so it never gets any children. Change it to:
if self.right == None:
self.right = TreeNode(value)
totaldict[value] = self.right
And do the same for left subtree.

Binary Search Tree Find minimum not clear

The logic I tried:
def min_tree_value(self):
while self.left:
self.left = self.left.left
return self.data
Actual Python program Logic:
def min_tree_value(self):
if self.left is None:
return self.data
return self.left.min_tree_value()
The actual Python program logic is in recursion form. I tried the same logic in While loop()
I'm not sure whether my logic is correct. Do help me to figure out the incorrect logic and point where I'm Wrong.
Your logic is almost there, but not quite:
def min_tree_value(self):
node = self
while node.left:
# don't change the structure by rebinding node.left,
# but iterate the tree by moving along nodes!
node = node.left
return node.data
Note that in the original code, you never reassign self before returning its value, so you always returned the root value.
First of all, the question asks about finding the minimum element in a binary tree.
The algorithm you used, will find the minimum element in the Binary Search Tree (as the leftmost element is the minimum).
For finding minimum element in a simple Binary Tree, use the following algorithm:
# Returns the min value in a binary tree
def find_min_in_BT(root):
if root is None:
return float('inf')
res = root.data
lres = find_min_in_BT(root.leftChild)
rres = find_min_in_BT(root.rightChild)
if lres < res:
res = lres
if rres < res:
res = rres
return res
Additions to the answer after OP changed the question:
The logic for the algorithm you tried is correct, with a small correction in the implementation: self = self.data. Both of them find the leftmost element.
I have also tested both the functions which return the same output:
class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data
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)
elif data > self.data:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
def findval(self, lkpval):
if lkpval < self.data:
if self.left is None:
return str(lkpval)+" Not Found"
return self.left.findval(lkpval)
elif lkpval > self.data:
if self.right is None:
return str(lkpval)+" Not Found"
return self.right.findval(lkpval)
else:
print(str(self.data) + ' is found')
def PrintTree(self):
if self.left:
self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
def min_tree_value_original(self):
if self.left is None:
return self.data
return self.left.min_tree_value_original()
def min_tree_value_custom(self):
while self.left:
self = self.left
return self.data
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
root.insert(3)
root.insert(1)
root.insert(0)
root.insert(-1)
root.insert(-2)
print(root.min_tree_value_original())
print(root.min_tree_value_custom())
Output:
-2
-2
Here -2 is the smallest and the leftmost element in the BST.

Why I get None when calling this method?

I want to write method mirror() which creates and return binary tree where all left subtrees become right subtrees and vice versa. I tried to do this with recursion:
def mirror(self):
if self.left == None and self.right == None:
return
elif self.left == None and self.right != None:
t = self.right
self.right = self.left
self.left = t
self.left.mirror()
elif self.left != None and self.right == None:
t = self.right
self.right = self.left
self.left = t
self.right.mirror()
else:
t = self.right
self.right = self.left
self.left = t
self.left.mirror()
self.right.mirror()
But I get output None. Why, and how to fix it?
Your current function swaps all the branches in-place; there's no particular need to return the tree, since you already have a reference to it if you managed to call the method in the first place. But if you want return such a reference anyway, you can:
def mirror(self):
if self.left == None and self.right == None:
pass
elif self.left == None and self.right != None:
t = self.right
self.right = self.left
self.left = t
self.left.mirror()
elif self.left != None and self.right == None:
t = self.right
self.right = self.left
self.left = t
self.right.mirror()
else:
t = self.right
self.right = self.left
self.left = t
self.left.mirror()
self.right.mirror()
return self
or more simply:
def mirror(self):
if self.left is not None:
self.left.mirror()
if self.right is not None:
self.right.mirror()
self.left, self.right = self.right, self.left
return self
If, on the other hand, you want a new tree independent of the original tree, you need to construct one to return.
def mirror(self):
new_tree = ... # Whatever you do to create a root node from the root of self
# If the child pointers aren't already None after creating the node
new_tree.left = None
new_tree.right = None
if self.right is not None:
new_tree.left = self.right.mirror()
if self.left is not None:
new_tree.right = self.left.mirror()
return new_tree

How to iterate over to rightmost leaf in a function

So I have this code:
def min_node(self):
while self.right != None:
self.data = self.right
return self.data
And I want it to keep iterating to the right until the next right is None, but for some reason self.right just stays the same value so the while loops goes on forever. Does anyone know how I can fix this?
Thank you.
What about recursion?
def min_node(self):
if self.right is None:
return self.data
return self.right.min_node()
Or iteratively?
def min_node(self):
result = self
while result.right is not None:
result = result.right
return result.data

python how to implement a list into a tree?

I have a list of data indicates what direction is going next like:
[[0,1,0,0,1],[0,0,1],[0,0],[0,1,1,1,0]]
I want to implement this data into a tree structure like:
The number inside the node is how many people walked on this direction.
I have a Tree class that I write myself like this:
class Tree(object):
def __init__(self):
self.left = None
self.right = None
self.data = 0
def insert(self,num):
self.data = self.data + 1
if num == 0:
if self.left == None:
self.left = Tree()
return self.left
elif num == 1:
if self.right == None:
self.right = Tree()
return self.right
How can I do this? I tried to make it in a recursive way but turns out it's not saving under root but build_tree which is a variable that I tried to make as the recursive pointer.
root = Tree()
for route in data:
build_tree = root
for i in range (0,len(route)):
num = route[i]
build_tree = build_tree.insert(num)
Thanks!
Edit: This code actually works just like Blender said in comment. I think I had something wrong when I implemented it to a more complex code.
Also thanks John La Rooy for the suggestion and Kevin K. for the example!
Try making a separate class for the node like so
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
Then in your Tree class initialize self.root and declare your functions with recursion within Tree
Edit: Here is an example.

Categories

Resources