How can I use a binary tree to compute a square root? - python

I want to compute the square root of a number by using a binary tree.
The thought process was to have a start point and the insert function would call the divide function when wanting to place in a node to either the left or the the right.
In my thought process I wanted the divide function to keep dividing until the number is divided evenly and it would return a value. If the number did not get divided evenly when the dividend hits 9, then it would just return the starting number.
I wanted the divide function to also return the dividend and that would go into the right side of the tree. The code I have submitted was supposed to output 4 2 and ['4','2']
I don't get any errors running the code, but when I run the code it's the output isn't lower then the initial starting number
Also this is my first time posting to StackOverFlow, I am a new programmer trying to learn data structures and algorithms. My logic is flawed so if I could get some tips that would be amazing. Thank you for you help!
class Square:
def __init__(self, start, dividend = 2):
self.start = start
self.right = None
self.left = None
self.num = self.start
self.value = None
self.dividend = dividend
def divide(self, num):
self.num = num
if self.num % self.dividend == 0:
return self.num / self.dividend
if self.dividend == 9:
return self.num
self.divide(num)
return self.dividend+1
def insert(self, num):
_noDivide = 3
_divide = 4
if self.start >= _noDivide:
self.value = self.divide(self.start)
if self.value == self.start:
if self.right is None:
self.right = Square(self.num)
else:
self.right.insert(self.num)
elif self.value >= _divide:
if self.left is None:
self.left = Square(self.num)
else:
self.left.insert(self.num)
else:
self.num = num
def PrintTree(self):
if self.left:
self.left.PrintTree()
print(self.num),
if self.right:
self.right.PrintTree()
def inorderTraversal(self, root):
res = []
if root:
res = self.inorderTraversal(root.left)
res.append(root.num)
res = res + self.inorderTraversal(root.right)
return res
def main():
root = Square(8)
root.insert(root.start)
root.PrintTree()
root.inorderTraversal(root)
if __name__ == '__main__':
main()

It seems that you want an exact surd form. Prime factorization will do. But to be fancy, here it is:
I'm not sure what do you mean by "the insert function would call the divide function when wanting to place in a node to either the left or the the right". But here is my implementation:
The dividend takes the left and the quotient takes the right. Always call divide on the right. Follow the prime factorization algorithm for divide. As a result, the product of all left in the binary tree is the prime factorization of the number. (Yeah so really does not require a binary tree.) The prime factorization can be easily converted to an exact surd form.

Related

Having issues trying to convert a binary search tree into a balanced search tree with just one method in python

class Node:
def __init__(self, data, left_child=None, right_child=None):
self.data = data
self.left_child = left_child
self.right_child = right_child
self.height = -1
class BinarySearchTree:
def __init__(self):
self.root = None
self.height = -1
self.balance = 0
def inorder(self):
return self.inorder_helper(self.root)
def inorder_helper(self, cur_node):
lyst = []
if cur_node is not None:
lyst += self.inorder_helper(cur_node.left_child)
lyst.append(str(cur_node.data))
lyst += self.inorder_helper(cur_node.right_child)
final_lyst = list(map(int, lyst))
return final_lyst
def rebalance_tree(self):
arr = self.inorder()
return self.rebalance_tree_helper(arr)
def rebalance_tree_helper(self, arr):
if not arr:
return None
mid = (len(arr)) // 2
root = Node(arr[mid])
root.left_child = self.rebalance_tree_helper(arr[:root])
root.right_child = self.rebalance_tree_helper(arr[root + 1:])
return root
bst.add(5)
bst.add(10)
bst.add(12)
bst.add(20)
bst.rebalance_tree()
print(bst)
Having issues trying to convert a binary search tree into a balanced search tree. So i currently have a binary search tree and it works correctly, 100%. However, I am trying to add a method that will balance the tree (aka turn it into an avl tree).
So i tried using https://www.geeksforgeeks.org/sorted-array-to-balanced-bst/ and tried making it a method into a tree, but i am having a few issues.
it keeps saying that i am reaching the recursion limit, and this is worrying me as i added these few lines of code that makes the recursion limit a lot higher then it should be needed:
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(10**6)
So now I am wondering if my method is running infinitely and causing the recursion limit, but i took a long look at the rebalance_helper and it looks like its not infinite.
If anyone can give me any insight i would really appreciate it. Thank you!

How can I sum all nodes under a given value in binary search tree?

My homework needs me to sum all numbers under the given value in a BST. However, I had no idea how to do it. Appreciate for any help.
class BinarySearchTree:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def search(self, find_data):
if self.data == find_data:
return self
elif find_data < self.data and self.left != None:
return self.left.search(find_data)
elif find_data > self.data and self.right != None:
return self.right.search(find_data)
else:
return None
def get_left(self):
return self.left
def get_right(self):
return self.right
def set_left(self, tree):
self.left = tree
def set_right(self, tree):
self.right = tree
def set_data(self, data):
self.data = data
def get_data(self):
return self.data
def create_new_bst(lst):
#creates a new tree with root node 55, and then inserts all the
#remaining values in order into the BST
def sum_beneath(t, value):
# don't know how to do
t = create_new_bst([55, 24, 8, 51, 25, 72, 78])
result = sum_beneath(t, 72)
print('Sum beneath 72 =', result)# should show 'Sum beneath 72 = 78'
I'm very new to BST so I really have no idea on how to start and do this question.
def insert(self, new_data):#can I just call this function in 'create_new_bst'?
if self.data:
if new_data < self.data:
if self.left is None:
self.left = BinarySearchTree(new_data)
else:
self.left.insert(new_data)
elif new_data > self.data:
if self.right is None:
self.right = BinarySearchTree(new_data)
else:
self.right.insert(new_data)
else:
self.data = data
Ok, as this is an exercise, I won't fill everything, but I will try to give you an idea of how it should be done:
You need to create your tree, in a simple way you can do this:
def create_new_bst(lst):
tree = BinarySearchTree(tree[0])
# And then, using the insert method, which is correct, add your nodes in the tree
return tree
First, you need to find Your subtree with the root 72
# Replace the pass with the appropriate code
def find_subtree(tree, value):
if value == tree.data: # This is found yeah !
pass
if value > tree.data: # Ok, this is not our data, we should look recursively in one of the children (I will not tell you which one). Maybe we can use find_subtree reccursively?
pass
if value < tree.data: # Same as above, but maybe we should look in the other child
pass
raise ValueError("Not found value " + str(value)) # Nothing has been found.
Now, you found the tree with my_tree = find_subtree(t, 72), you should just sum the left tree (if it exists) and the right tree (if it exists)
def sum_beneath(t, value):
my_tree = find_subtree(t, value)
s = 0
if my_tree.left is not None:
s += my_tree.left.sum_tree()
if my_tree.right is not None:
s += my_tree.right.sum_tree()
return s
Let's define the sum_tree method (in the class)! :)
def sum_tree(self):
ans = self.data
# Add the left sum reccursively
# Add the right sum reccursively
return ans
I hope this will help you to understand the concept of BST. If you need help do not hesitate to comment
It's quite an interesting problem to find the sum of nodes under a specific value, we can think of this of something like searching and transversing problem, there can be various ways to do this, but I can think of this something like-
Doing a binary search for the node.
Doing an (In-order, Post-Order or Pre-order) transversal, and saving the results of the returned nodes' values i.e. summing them up.
the big O time complexity I can think of should be something like-
for an nth node in the BST, log(n) should be the search time, then for the transversal (In-order, Post-Order or Pre-order), it should be m-n, where (m is the total number of nodes)
therefore, the total will be, (log(n) + m - n) ~ O(M).

Function to determine whether tree is a valid BST?

I have to determine whether given a list representing a tree, whether the tree is a valid BST (this question is taken from leetcode). I have seen other posts on this but I was wondering if someone could help me with my approach, since it is clearly not right. For example, for the tree [1,2,3] where 1 is the root, 2 is the left child, and 3 is the right child, my code returns true. Hopefully it only requires small changes, but it might be that the entire function's approach is incorrect.
Here is my code:
def isValidBST(self, root):
if (root == None):
return True
if (root.left == None or root.left.val < root.val):
return self.isValidBST(root.left)
if (root.right == None or root.right.val > root.val):
return self.isValidBST(root.right)
return False
Secondly, I have seen approaches with a helper function that takes in a min/max value, but that confuses me. If anyone would also like to explain why that approach is a good/better one, that would be greatly appreciated!
I'd make a min_max method for Nodes that finds the min and max values of the tree rooted at that Node. Do sanity checking while finding those, and then isValidBST can just catch the exception
def max_min(self):
'''
Returns maximum and minimum values of the keys of the tree rooted at self.
Throws an exception if the results are not correct for a BST
'''
l_max, l_min = self.left.max_min() if self.left else (self.val, self.val)
if l_max > self.val:
raise ValueError('Not a BST')
r_max, r_min = self.right.max_min() if self.right else (self.val, self.val)
if r_min < self.val:
raise ValueError('Not a BST')
return l_min, r_max
def isValidBST(self):
try:
if self.max_min():
return True
except ValueError:
return False
Here is one way to implement the validity check:
class BST:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def isValidBST(self):
'''
Simultaneously check for validity and set our own min and max values.
'''
self.min = self.max = self.value
if self.left:
if not self.left.isValidBST():
return False
if self.left.max >= self.value:
return False
self.min = self.left.min
if self.right:
if not self.right.isValidBST():
return False
if self.right.min < self.value:
return False
self.max = self.right.max
return True
assert BST(2, BST(1), BST(3)).isValidBST()
case = BST(2, BST(1, None, BST(3)))
assert case.left.isValidBST()
assert not case.isValidBST()

Implementing Binary Search Tree (Python)

I have the task to perform some basic operations on Binary Search Trees and I'm not sure what is the clever way to do it.
I know that the usual way would be to write a class for the nodes and one for the tree so that I can build up my tree from given values and perform certain tasks on it. The thing is, I'm already getting the tree as a list and since BSTs are not unique, there won't come any good from it if I take each value and build the tree myself.
So... I'm getting a list like this:
11 9 2 13 _, 4 18 2 14 _, 2 10 _ 11 4, 14 16 4 _ _, 13 0 11 _ _ | 10 | 7
which means:
key value parent left right, ... | value1 | value2
So as you see the BST is given explicitly. My tasks are to do a level-print of the tree, return the path from root to value1, do a rotate-right operation on the subtree that has value1, then delete value1 and then insert value2.
What would be an efficient way to tackle this problem?
Here is one possible way of implementing the tree. Hope it helps. Though this contains insertions and popular traversals, not rotations or deletions.
Reference: http://www.thelearningpoint.net/computer-science/learning-python-programming-and-data-structures/learning-python-programming-and-data-structures--tutorial-20--graphs-breadth-and-depth-first-search-bfsdfs-dijkstra-algorithm-topological-search
'''
Binary Search Tree is a binary tree(that is every node has two branches),
in which the values contained in the left subtree is always less than the
root of that subtree, and the values contained in the right subtree is
always greater than the value of the root of the right subtree.
For more information about binary search trees, refer to :
http://en.wikipedia.org/wiki/Binary_search_tree
'''
#Only for use in Python 2.6.0a2 and later
from __future__ import print_function
class Node:
# Constructor to initialize data
# If data is not given by user,its taken as None
def __init__(self, data=None, left=None, right=None):
self.data = data
self.left = left
self.right = right
# __str__ returns string equivalent of Object
def __str__(self):
return "Node[Data = %s]" % (self.data,)
class BinarySearchTree:
def __init__(self):
self.root = None
'''
While inserting values in a binary search tree, we first check
whether the value is greater than, lesser than or equal to the
root of the tree.
We initialize current node as the root.
If the value is greater than the current node value, then we know that
its right location will be in the right subtree. So we make the current
element as the right node.
If the value is lesser than the current node value, then we know that
its right location will be in the left subtree. So we make the current
element as the left node.
If the value is equal to the current node value, then we know that the
value is already contained in the tree and doesn't need to be reinserted.
So we break from the loop.
'''
def insert(self, val):
if (self.root == None):
self.root = Node(val)
else:
current = self.root
while 1:
if (current.data > val):
if (current.left == None):
current.left = Node(val)
break
else:
current = current.left
elif (current.data < val):
if (current.right == None):
current.right = Node(val)
break
else:
current = current.right
else:
break
'''
In preorder traversal, we first print the current element, then
move on to the left subtree and finally to the right subree.
'''
def preorder(self, node):
if (node == None):
return
else:
print(node.data, end=" ")
self.preorder(node.left)
self.preorder(node.right)
'''
In inorder traversal, we first move to the left subtree, then print
the current element and finally move to the right subtree.
'''
#Important : Inorder traversal returns the elements in sorted form.
def inorder(self, node):
if (node == None):
return
else:
self.inorder(node.left)
print(node.data, end=" ")
self.inorder(node.right)
'''
In postorder traversal, we first move to the left subtree, then to the
right subtree and finally print the current element.
'''
def postorder(self, node):
if (node == None):
return
else:
self.postorder(node.left)
self.postorder(node.right)
print(node.data, end=" ")
tree = BinarySearchTree()
tree.insert(1)
tree.insert(9)
tree.insert(4)
tree.insert(3)
tree.insert(5)
tree.insert(7)
tree.insert(10)
tree.insert(0)
print ("Preorder Printing")
tree.preorder(tree.root)
print("\n\nInorder Printing")
tree.inorder(tree.root)
print("\n\nPostOrder Printing")
tree.postorder(tree.root)
Here is the implementation of Binary Search Tree with it's basic operations like insert node, find node
class Node:
def __init__(self,data):
self.left = None
self.right = None
self.data = data
class BST:
def __init__(self):
self.root = None
def set_root(self,data):
self.root = Node(data)
def insert_node(self,data):
if self.root is None:
self.set_root(data)
else:
n = Node(data)
troot = self.root
while troot:
if data < troot.data:
if troot.left:
troot = troot.left
else:
troot.left = n
break
else:
if troot.right:
troot = troot.right
else:
troot.right = n
break
def search_node(self,data):
if self.root is None:
return "Not found"
else:
troot = self.root
while troot:
if data < troot.data:
if troot.left:
troot = troot.left
if troot.data == data:
return "Found"
else:
return "Not found"
elif data > troot.data:
if troot.right:
troot = troot.right
if troot.data == data:
return "Found"
else:
return "Not found"
else:
return "Found"
tree = BST()
tree.insert_node(10)
tree.insert_node(5)
tree.insert_node(20)
tree.insert_node(7)
print(tree.root.data)
print(tree.root.left.data)
print(tree.root.right.data)
print(tree.root.left.right.data)
print(tree.search_node(10))
print(tree.search_node(5))
print(tree.search_node(20))
print(tree.search_node(7))
print(tree.search_node(12))
print(tree.search_node(15))
Output:
10
5
20
7
Found
Found
Found
Found
Not found
Not found
In this specific case I had success using a dictionary as a datatype to store the graph. The key is the node_key and the value is a list with the attributes of the node. In this way it is rather fast to find the needed nodes and all its attributes.
I'm just not sure if there is a way to make it reasonably faster.

How can I recursively insert the Fibonacci sequence into a binary tree

Hope someone can help, I'm not a programmer, but have been interested in exploring Fibonacci sequence and it's recursive tree...
I've created a Binary Tree class, along with an associated TreeNode class, and want to generate a binary tree of the recursive calls created by:
f(n) = f(n-1) + f(n-2) for a given value of n
I'd want to add it as an InsertFibonacci method of my Binary Tree class, replacing the standard Insert method:
def insertNode(self, root, inputData):
if root == None:
return self.addNode(inputData)
else:
if inputData <= root.nodeData:
root.left = self.insertNode(root.left, inputData)
else:
root.right = self.insertNode(root.right, inputData)
return root
Would I add somekind of decorator to the Fib function?
# Fib function
def f(n):
def helper(n):
left = f(n-1)
right = f(n-2)
return left,right
if n == 0:
return 0
elif n == 1:
return 1
else:
left, right = helper(n)
return left + right
Here's the simplest solution I can think of:
class FibTree(object):
def __init__(self, n):
self.n = n
if n < 2:
self.value = n
else:
self.left = FibTree(n - 1)
self.right = FibTree(n - 2)
self.value = self.left.value + self.right.value
Here's one way:
def insertFibonacci(self, n):
current = self.addNode(n)
if n > 1:
current.left = self.insertFibonacci(n-1)
current.right = self.insertFibonacci(n-2)
# if you want the fibonacci numbers instead of the calls:
# current.value = current.left.value + current.right.value
return current
Assumes positive n.
Should return the root of the fibonacci call tree.
Note that this won't exactly be the same kind of binary tree; it won't satisfy the ordering invariant that a binary search tree does. I'm assuming you just want to use your existing structure for convenience.

Categories