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.
Related
I'm currently working on LeetCode problem 108. Convert Sorted Array to Binary Search Tree:
Given an integer array nums where the elements are sorted in ascending order, convert it to a height-balanced binary search tree.
A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.
My code seems to be working fine but I don't know how to display the value null instead of None in my list. I need to print the BST in level order traversal. I'm looking for advice, hints or suggestions.
Input:
[-10,-3,0,5,9]
My current output:
[0, -3, 9, -10, None, 5, None]
Accepted output:
[0,-3,9,-10,null,5]
Here is my code:
from queue import Queue
from typing import Optional
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def sortedArrayToBST(nums: [int]) -> Optional[TreeNode]:
nbNodes = len(nums)
if nbNodes == 1:
root = TreeNode()
root.val = nums[0]
return root
elif nbNodes == 0:
root = TreeNode()
root.val = None
return root
middle = int(nbNodes / 2)
root = TreeNode()
root.val = nums[middle]
leftList = []
rightList = []
j = middle + 1
for i in range(middle):
leftList.append(nums[i])
if j != nbNodes:
rightList.append(nums[j])
j += 1
root.left = sortedArrayToBST(leftList)
root.right = sortedArrayToBST(rightList)
return root
def levelorder(root):
if root==None:
return
Q=Queue()
Q.put(root)
level_order_list = []
while(not Q.empty()):
node=Q.get()
if node==None:
continue
level_order_list.append(node.val)
Q.put(node.left)
Q.put(node.right)
print(level_order_list)
if __name__ == "__main__":
container = [-10,-3,0,5,9]
levelorder(sortedArrayToBST(container))
This is kind of a weird requirement that has nothing to do with the apparent main point of the problem and I suspect it's a result of the description being copied over from one that's aimed at another language (like Javascript, which uses null instead of None).
You can, however, format your list however you like when you print it; here's an example where we print a list by joining each item with "," (instead of the default ", ") and replace None with "null":
>>> my_list = [0, -3, 9, -10, None, 5, None]
>>> print("[" + ",".join("null" if i is None else str(i) for i in my_list) + "]")
[0,-3,9,-10,null,5,null]
Since JSON renders None as null, another option would be to dump the list to JSON and remove the " " characters:
>>> import json
>>> print(json.dumps(my_list).replace(' ', ''))
[0,-3,9,-10,null,5,null]
The problem is not related to null or None. LeetCode is a platform for taking code challenges in many different languages and they use JSON style to describe input/output, and in JSON notation None translates to null.
Not to worry about that. However, when you look at your output, there is a trailing None that should not be there. That means that you returned a BST that has a node with a None value. This should not happen.
The code that creates this None valued node is easy to identify... it is here:
elif nbNodes == 0:
root = TreeNode()
root.val = None
return root
return
When you think of it, this cannot be right: the number of nodes to generate (nbNodes) is 0, yet your code creates 1 node -- and that is one too many! In this case you should just return None to indicate that the parent node has no child here.
So replace with:
elif nbNodes == 0:
return
This fixes the issue you mentioned, and your code will now pass all tests on LeetCode.
Here is your code with the above corrections and with the self parameter restored (which you had removed to run it without the need to create a class instance):
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
nbNodes = len(nums)
if nbNodes == 1:
root = TreeNode()
root.val = nums[0]
return root
elif nbNodes == 0:
return
middle = int(nbNodes / 2)
root = TreeNode()
root.val = nums[middle]
leftList = []
rightList = []
j = middle + 1
for i in range(middle):
leftList.append(nums[i])
if j != nbNodes:
rightList.append(nums[j])
j += 1
root.left = self.sortedArrayToBST(leftList)
root.right = self.sortedArrayToBST(rightList)
return root
Other improvements
Unrelated to your question, but there are several things you can optimise:
Try to avoid creating new lists (leftList, rightList): copying values into them takes time and space. Instead use start/end indices in the original list to denote which sublist is currently processed.
Make use of the additional arguments you can pass to the TreeNode constructor. That way you don't have to assign to attributes after the constructor has run.
Use the integer division operator instead of the floating point division operator.
One of the two base cases is not needed as it would be dealt with correctly by the next recursive calls.
Here is a spoiler solution that applies those remarks:
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
def recur(start: int, end: int):
if start < end:
middle = (start + end) // 2
return TreeNode(nums[middle],
recur(start, middle),
recur(middle + 1, end))
return recur(0, len(nums))
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.
For more basic information (for starters)... you may want to read this question:
How to Implement a Binary Tree?
For more information on how to implement a binary tree... you may want to open this site:
http://www.openbookproject.net/thinkcs/python/english2e/ch21.html
The binary operation tree is way different from its father... the Binary Tree. This is the expression tree for the string '(7+3)(5-2):Expression Tree for (7+3)(5-2).
The snippet way way below should do the following...
Read a string
When it encounters '(', then it creates a new node and goes to the left child of the current node
When it encounters any digit, it places the data then goes up
When it encounters an operator '+','-','*','/', then it places the data then goes to the right child of the current node
When it encounters ')', then it backtracks and goes up.
There are few problems with this code that need to be solved...
the int(strng) does not function well in this code: BinaryOperationTree instance has no attribute 'len'
Or maybe you may add your own code to answer this question... If you do this, then you may disregard the code below. Take note that it should print the nodes infix, prefix, and postfix...
class Node:
def __init__ (self, data, currNode):
self.data = data
self.left = None
self.right = None
self.parent = currNode
currNode = self.right
return currNode
class BinaryOperationTree():
def __init__(self):
strng = raw_input('Please enter the operation to turn it into a binary tree.\n')
print strng
def readCharacter(self):
for i in range(-1, str_len, -1):
k = k + 1
if (k >= 2):
j = j * 16
l = 0 #Counter
currNode = Node
while (l <= k - 1):
if isDigit(hexa[l]):
encntrDigit(hexa[l], currNode)
elif isRPar(hexa[l]):
enctrRpar(currNode)
elif isLPar(hexa[l]):
enctrLpar(currNode)
elif isOperator(hexa[l]):
enctrOperator(hexa[1], currNode)
def isDigit(x):
chars = ['0','1','2','3','4','5','6','7','8','9']
if chars in x:
return True
else:
return False
def isRPar(x):
if ')' in x:
return True
else:
return False
def isLPar(x):
if '(' in x:
return True
else:
return False
def isOperator(x):
chars = ['+','-','*','/']
if chars in x:
return True
else:
return False
def encntrDigit(x, currNode):
currNode.data = x
currNode = currNode.parent
return currNode
def enctrRpar(self, currNode):
currNode = currNode.parent
def enctrLPar(self, currNode):
currNode = Node()
def enctrOperator(self, x, currNode):
currNode.data = x
currNode = currNode.parent
#Prints the tree in Pre-Order Format
def preOrder (node):
if (node is not None):
print node.data, "",
preOrder(node.left)
preOrder(node.right)
#Prints the tree in Order Format
def inOrder (node):
if (node is not None):
inOrder (node.left)
print node.data, "",
inOrder (node.right)
#Prints the tree in Post-Order Format
def postOrder (node):
if (node is not None):
postOrder (node.left)
postOrder (node.right)
print node.data, "",
def main():
string = BinaryOperationTree()
string.readCharacter()
main()
I'm practicing creating a balanced binary search tree in python.
I already have these below, any idea on how to create a balance_bst funtion that passed a list of unique values that are
sorted in increasing order. It returns a reference to the root of a well-balanced binary search tree:
class LN:
def __init__(self,value,next=None):
self.value = value
self.next = next
def list_to_ll(l):
if l == []:
return None
front = rear = LN(l[0])
for v in l[1:]:
rear.next = LN(v)
rear = rear.next
return front
def str_ll(ll):
answer = ''
while ll != None:
answer += str(ll.value)+'->'
ll = ll.next
return answer + 'None'
# Tree Node class and helper functions (to set up problem)
class TN:
def __init__(self,value,left=None,right=None):
self.value = value
self.left = left
self.right = right
def height(atree):
if atree == None:
return -1
else:
return 1+ max(height(atree.left),height(atree.right))
def size(t):
if t == None:
return 0
else:
return 1 + size(t.left) + size(t.right)
def is_balanced(t):
if t == None:
return True
else:
return abs(size(t.left)-size(t.right)) <= 1 and is_balanced(t.left) and is_balanced(t.right)
def str_tree(atree,indent_char ='.',indent_delta=2):
def str_tree_1(indent,atree):
if atree == None:
return ''
else:
answer = ''
answer += str_tree_1(indent+indent_delta,atree.right)
answer += indent*indent_char+str(atree.value)+'\n'
answer += str_tree_1(indent+indent_delta,atree.left)
return answer
return str_tree_1(0,atree)
How do write the balance_bst?
def balance_bst(l):
Here is what I did:
def build_balanced_bst(l):
if l == None:
return None
else:
middle = len(l) // 2
return TN(l[middle],
build_balanced_bst(l[:middle]),
build_balanced_bst(l[middle + 1:]))
It gives me:
IndexError: list index out of range
How do I fix it?
I'm not going to write it for you since that's not what SO is about, but here's the general idea. Since the list is already sorted, the root should be the element in the middle of the list. Its left child will be the root of the balanced tree consisting of the elements to the left of the root in the list, and the right sub-tree will be the rest.
How would I be able to create common tree operations such as insert and search while passing in functions to reduce redundancy. For example, a recursive function calls itself on the left branch when the value passed in is greater than the current node. If I were able to pass in functions like insert and search, I'd be able to factor out a lot of the traversal. The main problem area I'm seeing is that both functions have different base cases. Example solutions in python would be appreciated.
def insert(n, node = root):
if node == None:
node.data = n
node.left, node.right, node.middle = None
elif node.data == n:
insert(node.middle)
elif node.data < n:
insert(right)
else:
insert(left)
def search(n, node = root):
if node == None:
return false
elif node.data == n:
return true
elif node.data < n:
search(right)
else:
search(left)
Your logic for inserting is not correct. You are trying to set attributes on None.
For reusing common code you can use function decorators. Implement common code for traversing tree in decorator function and action on found element in operation function. You can change your code as follow:
def tree_operation(f):
def recursive_wrapper(n, node):
if node == None or node.data == n:
# tree traversed to final point. do action for found element or
# None
return f(n, node)
# try getting closer to interesting element
elif node.data < n:
return recursive_wrapper(n, node.right)
else:
return recursive_wrapper(n, node.left)
return recursive_wrapper
#tree_operation
def search(n, node):
if node == None:
return False
elif node.data == n:
return True
#tree_operation
def insert(n, node):
if node == None:
# this obviously fail
node.data = n
node.left, node.right, node.middle = None
elif node.data == n:
insert(node.middle)
In fact it passes functions, as you noted in question plus renames resultant function to passed in function. Above decorator syntax for insert function does this:
insert = tree_operation(insert)
I think its better to not combine the iterative part of functions in a single one because it complicates the code. But if you think that the iterative part is complex and you need to write it once, you can re-factor it as follow:
def do_iterate(base_function, n, node=root):
if node == None or node.data == n:
base_function(n, node)
elif node.data < n:
do_iterate(base_function, n, node.right)
else:
do_iterate(base_function, n, node.left)
Then, you can write your own base_function that will be called when the base conditions met. For example you can use base_insert() and base_search() functions in place of insert() and search() functions.
def base_insert(n, node):
if node == None:
node.data = n
node.left, node.right, node.middle = None
else:
do_iterate(base_insert, n, node.middle)
def base_search(n, node):
if node == None:
return false
else:
return true
So you can use your algorithms like below:
do_iterate(base_insert, 7)
do_iterate(base_search, 4)
At the end, I'm not sure it's better than your simple code.