I'm fairly new to programming and I want to screw around with some Binary Search Trees. I want to make a function that counts the number of nodes in the tree recursively, however, when I run my function it doesn't seem to work and it keeps returning 'none' as if there is nothing in my tree. Could anyone help me find the problem here?
This is my TreeNode class:
class TreeNode(object):
def __init__(self, data = None, left=None, right=None):
self.item = data
self.left = left
self.right = right
def __str__(self):
return str(self.item)
This is my main function, I trimmed most of it down just so we can get to the problem referring to the counting of the nodes.
from TreeNode import TreeNode
class BST(object):
#------------------------------------------------------------
def __init__(self):
"""create empty binary search tree
post: empty tree created"""
self.root = None
def treeSize(self, root, size = 0):
if root is None:
return -1
if root is not None:
size += 1
if root.left is not None:
self.treeSize(root.left, size)
if root.right is not None:
self.treeSize(root.right, size)
This is the code I use to test out my function:
from BinarySearchTree import BST
from TreeNode import TreeNode
tree = TreeNode(4, TreeNode(2, TreeNode(1), TreeNode(3)), TreeNode (7, TreeNode(6),TreeNode(8)))
a = BST()
print(a.postOrder(tree))
print(a.treeSize(tree))
When I called the 'print(a.treeSize(tree))' It just returns 'none' and not '7' like it should.
You can also do it the good old recursive way:
def treeSize(self, root):
if root is None:
return 0
if root is not None:
return 1 + self.treeSize(root.left) + self.treeSize(root.right)
Jonathan's answer is nice as well.
I see. You think size is going to get updated in the called functions. It won't as it's local to each function. You could call global on it, but that's not optimal.
You could set it as a member variable (don't actually do it this way):
def __init__(self):
...
self.size = 0
def treeSize(self,...):
...
self.size += 1
...
return self.size
but the obvious bug is self.size will double every time treeSize is called. You can fix that too, but let's use patterns we know and love. Do it the good old recursive way like VHarisop wrote.
Related
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!
I'm trying to implement a binary tree with insert and preorder methods.
After adding elements to the tree, only one element is displayed.
Can someone let me know where I'm wrong.
Below is code:
class Node(object):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = None
self.right = None
def __repr__(self):
return '{}'.format(self.value)
class BinaryTree(object):
def __init__(self, root=None):
self.root = root
def add(self, value):
val = self.root
if not val:
self.root = value
val = value
elif not val.left:
val = value
elif not val.right:
val = value
else:
self.left = val.left.add(value)
return val
def preorder(self):
val = self.root
if not val: # this will handle the case when root node is None.
return
print(val)
if val.left:
val.left.preorder()
if val.right:
val.right.preorder()
def main():
binary_tree = BinaryTree()
print("Adding nodes to the tree")
for i in range(1, 11):
node = Node(i)
binary_tree.add(node)
print("Printing preorder...")
binary_tree.preorder()
if __name__ == '__main__':
main()
Output
Adding nodes to the tree
Printing preorder...
1
Your code has a few different errors. Some relate to how you modify self.root (or fail to), others have to do with attempts at recursion on the wrong types.
The first issue, which is why your code fails silently, has to do with your BinaryTree.add method, which does nothing when the tree is empty. The problem is that you initialize a local variable val to be equal to your root node (if you have one), and then later rebind it to some other value. But that never changes the root value at all, only the local val variable.
I suggest you get rid of val all together, and instead read and write self.root directly. Then you'll actually make some progress, and see the other issues.
Here's a start:
def add(self, value):
if self.root is None:
self.root = value
elif self.root.left.left is None:
self.root.left = value
...
The other issues I mention are both similar, though one occurs in BinaryTree.add and the other in BinaryTree.preorder. The issue is that you try to call the same method (add or preorder) on one of the children of your root node. But the nodes are Node instances, and don't have the methods that you've defined in the BinaryTree class.
This issue doesn't have as obvious a solution as the previous one. One idea might be to move the logic for the methods into the Node class (where you can recurse easily), and leave only the empty-tree handling code in the BinaryTree methods (everything else gets delegated to the root node).
I was wondering if someone can review my code for level order traversal in a BST. I am suppose to have [[3],[9,20],[15,7]] but instead I get [[3],[9],[20],[15],[7]] I know I need an outer while loop but, not sure how to construct it.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
import queue
class Solution(object):
def levelOrder(self, root):
L = queue.Queue()
local = []
L.put(root)
while not L.empty():
node = L.get()
local.append([node.val])
if(node.left):
L.put(node.left)
if(node.right):
L.put(node.right)
return local
Below code is a simple implementation of BFS in Python. I able to print the values level by level from a tree. However when I want to search a element and print it . I am not able to do it. Whts is the error?
def search_bfs(self,root,key):
q=QueueClass()
q.enqueue(root)
while q.size() > 0:
curr_node = q.dequeue()
#print curr_node
#print key
if curr_node == key:
print curr_node
break
if curr_node.left is not None:
q.enqueue(curr_node.left)
if curr_node.right is not None:
q.enqueue(curr_node.right)
from QueueClass import QueueClass
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
def __str__(self):
return str(self.data)
class searchtree:
def __init__(self):
self.root = None
def create(self,val):
if self.root == None:
self.root=Node(val)
else:
current=self.root
while 1:
if val < current.data:
if current.left:
current=current.left
else:
current.left=Node(val)
break
if val > current.data:
if current.right:
current=current.right
else:
current.right=Node(val)
break
else:
break
tree=searchtree()
lst=[3,1,2,6,4,5,8,12]
for i in lst:
tree.create(i)
tree.search_bfs(tree.root, 3)
You really make it hard to reproduce your problem! So here's what I did:
class QueueClass(object):
def __init__(self):
self.l = []
def size(self): return len(self.l)
def enqueue(self, it): self.l.append(it)
def dequeue(self): return self.l.pop()
class Node:
def __init__(self, name, left=None, right=None):
self.name = name
self.left = left
self.right = right
def __str__(self):
return '{}:{}/{}'.format(self.name, self.left, self.right)
root = Node('root')
adding all the code you omitted (more than you supplied!-).
And now, adding your code exactly as reported, the call:
search_bfs(None, root, root)
emits
root:None/None
exactly as desired and contrary to your report.
It follows that your bug is in some of code you didn't show us, not in the coded you did show.
You either have a buggy queue-class, or are building a different tree than you thought, or searching for a node that is not actually in the tree.
Hard to debug code you're now showing, you know.
Added: so now I've integrated the extra code per your edit and at the end I have:
st = searchtree()
st.create('imtheroot')
st.search_bfs(st.root, st.root)
and of course it prints imtheroot as expected.
Is your bug perhaps STILL hiding in parts you're not yet showing, e.g instead of looking for a node you may be looking for something else?
E.g, if the final call was erroneously st.search_bfs(st.root, 'imtheroot') then obviously the search would fail -- you're checking equality of the key parameter with a node, so key clearly must be a node. not a string or other things (unless the Node class defines a very, very peculiar __eq__ method, which the one you've shown fortunately doesn't:-).
I think the issue is that when you do if curr_node == key, curr_node is a Node object, which has an integer .data attribute, but key is the integer value.
So I think you just need to use if curr_node.data == key.
I am reviewing for my final and one of the practice problem asks to implement a function that puts a value into a binary search tree in Python. Here is the Tree implementation I am using.
class Tree(object):
def __init__(self, entry, left=None, right=None):
self.entry = entry
self.left = left
self.right = right
Here is the function I need to fill in.
def insert(item, tree):
"""
>>> t = Tree(5, Tree(1, None, Tree(4)), Tree(7, Tree(6), Tree(8)))
>>> insert(2, t)
>>> t
Tree(5, Tree(1, None, Tree(4, Tree(2), None)), Tree(7, Tree(6), Tree(8)))
"""
Can anyone help me implement this code, as I have no idea where to start? Thanks!
def insert(item, tree):
if (item < tree.entry):
if (tree.left != None):
insert(item, tree.left)
else:
tree.left = Tree(item)
else:
if (tree.right != None):
insert(item, tree.right)
else:
tree.right = Tree(item)
Tree is a Non linear data structure.A tree is created by set of vertices and set of edges.Average searching complexity is logn . Let's consider how to insert values to tree.
First of all , you would create a Vertices.In another way, you would create nodes.then , Those nodes which is created insert hierarchical manner.In creating Node class , You can initialize all the properties of Node class in constructor function.Actually like this,
class Node:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
At beginning, Node's data=data, left child of Node is None and right child of Node is None.And then , you can create a binary search tree using those created nodes.
class tree:
def __init__(self):
self.root=None
def insert(self,data):
if(self.root==None):
self.root=Node(data)
else:
self._insert(data,self.root)
def _insert(self, data, curNode):
if(curNode.data>data):
if(curNode.left==None):
curNode.left=Node(data)
else:
self._insert(data,curNode.left)
else:
if(curNode.right==None):
curNode.right=Node(data)
else:
self._insert(data,curNode.right)
At first, root node is initialized under constructor method of tree class.And then insert nodes using insert function.Using any tree traversal method can be printed elements of tree..I think , you could understand.thank you!