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
Related
As part of a project I have to implement a BST with the purpose of sorting through a big dictionary of keys and values. However, I'm having some problems with my code. Specifically, I get an error message because I've exceeded the maximum recursion limit.
Here is the code:
#dataclass
class Node:
key: Any = None
value: Any = None
left: Any = None
right: Any = None
def put(self, key, value):
new_node = Node(key, value)
if new_node.value < self.value:
if self.left is None:
self.left = Node(key, value, None, None)
else:
self.put(key, value)
elif new_node.value > self.value:
if self.right is None:
self.right = Node(key, value, None, None)
else:
self.put(key, value)
I understand I've created an infinite recursive function, but I dont understand why. Looking at it, it seems to me that it should not be infinite. Can someone tell me what I've done wrong?
As far as I can see, your recursive calls self.put(key, value) are identical (same arguments) to the initial call, which causes the infinite loop; think about how you want your algorithm to behave (simulating the process on a diagram helps).
For future reference, here's the fixed code (only fixes the issue mentioned in the questions; there's still room for improvements).
#dataclass
class Node:
key: Any = None
value: Any = None
left: Any = None
right: Any = None
def put(self, key, value):
new_node = Node(key, value)
if new_node.value < self.value:
if self.left is None:
self.left = Node(key, value, None, None)
else:
self.left.put(key, value)
elif new_node.value > self.value:
if self.right is None:
self.right = Node(key, value, None, None)
else:
self.right.put(key, value)
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.
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.
Hi my question is how can i fix the code for my add function for my binary search tree program.
class BTNode2:
def __init__(self,d,l,r):
self.data = d
self.left = l
self.right = r
self.mult = 1
And this is the add method
def add(self, d):
if (self < d.data):
if (d.left != None):
add(self, d.left)
else:
d.left = BTNode2(self)
else:
if (d.right != None):
add(self, d.right)
else:
d.right = BTNode2(self)
return
This is the error i get when i try to run the add method:
AttributeError: 'str' object has no attribute 'data'
In essence, you swapped the parameters of the add function, since self is the tree here, and d the data element to add. Furthermore in order to construct such BTNode2s with only one parameter, you should add a default value for l and r. Finally depending on what mult does, you might want to change this in the add algorithm, but it is not really clear what it represents.
So we can fix this to:
class BTNode2:
def __init__(self, d, l=None, r=None):
self.data = d
self.left = l
self.right = r
self.mult = 1
def add(self, d):
if d < self.data:
if self.left is not None:
self.left.add(d)
else:
self.left = BTNode2(d)
else:
if self.right is not None:
self.right.add(d)
else:
self.right = BTNode2(d)
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.