Recursion and Binary Trees - python

#Get length of the longest path through recursion
def max_height(node):
if not node:
return 0
left = max_height(node.left) #Base Case based on my understanding
right = max_height(node.right) #Base Case based on my understanding
return max_height(left, right) + 1
I keep calling the max_height to get the length but I'm getting an error. I've thought of three possibilities:
1) I misunderstand the concept of the base case and I don't actually have a base case.
2) I'm not properly spacing Python code.
3) I'm not recursively getting the height of the BST at all but rather the width of the tree, which is affecting later calculations.
I know it is similar to this question, but the main difference is that I'm really trying to use recursion , where the other question used iteration and merely called it recursion.
how to find the height of a node in binary tree recursively

The base case is where the recursion stops and you have one: not node (node == None)
I don't see an issue with the spacing... Make sure you use only tabs or only spaces
This does produce the height: the number of nodes from root to leaf along the longest root-leaf path. At every node level, you add 1, and follow the higher subtree.
def max_height(node):
if not node: # this is the base case:
return 0 # where all recursive calls eventually stop
left = max_height(node.left) # <- these are the recursive calls:
right = max_height(node.right) # <- function x is called inside function x
return max(left, right) + 1 # max here, not max_height
Note that this is merely a more verbose version of this answer to the question you linked.

All answered were right but, I faced little problem while writing inside the class;
So, the code goes like this, I hope this helps.
class Tree(object):
def height(self, root):
if root == None: #root == None
return 0
else:
return 1 + max(self.height(root->left), self.height(root->left))
t = Tree()
t.height(t)

Related

Counting the leaves of a binary tree using recursion: the final return statement of (recursive function)+(recursive function)

I have been learning binary trees lately and have looked through the code for counting the leaves.
This is the recursive function to count the leaves:
def __count_leaves_recursive(self, node):
if node == None:
return 0
elif node.left == None and node.right == None:
return 1
else:
return self.__count_leaves_recursive(node.left) + self.__count_leaves_recursive(node.right)
When learning how recursion works with trees, the Python Tutor visualisation tool has been invaluable. However it hasn't helped me visualise the final return statement. I am struggling to visualise what's happening when a recursion function is added to another recursive function in the same line.
Is it simply the same as any other time the program reaches a recursive function? In that, the program simply records where it enter the function in order to return to the same spot when the function has been completed?
Is it simply the same as any other time the program reaches a recursive function?
Yes, you can image that line of code like this:
a = self.__count_leaves_recursive(node.left)
b = self.__count_leaves_recursive(node.right)
return a + b
So the first recursive call has to finish completely before the second one is launched. When that second recursive call also has finished its job, both returned values are summed up, and that value is returned to the caller.

Create a Tree of Object Recursively (Python)

i would like to create a tree of objects called State.
Each State has a list of 4 robots and each states have differents robots coordinates.
The goal is to create a graph which will be solved by a Breadth First Search Algorithm.
(The original game is RicochetRobot maybe you guys know it).
class State:
def __init__(self,parent,childs,robots,cpt,):
self.parent = parent
self.childs = childs
self.robots = robots
self.cpt = cpt
I created a function create_child to do this
def create_child(self,depth):
#UP
#Depth is the tree height
if depth==0:
print("STOP")
return
else :
for i in range(4):
#Copying the robots of the current object
temp = copy.deepcopy(self.robots)
#Getting robot to move index
temp_robot = temp[i]
#removing this robot from the list
temp.pop(i)
#Moving up the robot and inserting it in the list
#Moving up is a simple function which increment the y of the robot
temp.insert(i,moving_up(temp_robot,create_board(init_robot())))
#Adding a new child into childs list
self.childs.append(State(self,self.childs,temp,self.cpt+1))
#Decrementing the depth
depth-=1
#Recursivity
for child in self.childs:
child.create_child(depth)
My problem is that when depth = 0 , it print STOP,but it doesnt return None, and the function keep going.
Anynone knows from where it come froms?
Also, if you can give advice on how to make my tree in an easier way it would be nice.
Alright so i think i found a solution , here it is :
depth = 1
parent = Initial_State
for j in range(depth):
for i in range(len(parent.childs)-1):
parent.childs[i].create_child()
parent = parent.childs[i]
It seems to be working. I dont use recursion anymore, i do it in a more iterative way and outside the function and it seems good.
Thank you

A* (A star) search algorithm implementation still not working

I haven't gotten a response on my other post since I updated it and I really need some help, so I'm reposting. The code below is the important bit, but a link to the full code is here: https://github.com/amstrudy/nao-ncsu/blob/master/oop_a_star.py
I've been following along the Wikipedia pseudocode for an A * implementation in Python. My code reaches the goal, but I can't seem to figure out how to reconstruct the actual path. It doesn't work because the piece of code where cameFrom is updated is only updated once at the end when the goal is reached. I don't understand that really but it's how the wikipedia article had the pseudocode.
def a_star ():
# create node object for home
home_node = Node(home, goal, home)
# set of nodes already evaluated
closedSet = []
# set of currently discovered nodes that are not evaluated yet
# initially, only the start node is known
openSet = [home_node]
while len(openSet) != 0:
minIndex = 0;
for i in list(range(len(openSet))):
if openSet[i] < openSet[minIndex]:
minIndex = i
cur_node = openSet[minIndex] # expand on node with smallest fScore
cur_node.generateNeighbors() # make new nodes to check
if cur_node.location == home_node.goal:
print("Made it to the goal!")
return reconstruct(cur_node)
openSet.pop(minIndex)
closedSet.append(cur_node)
for neighbor in cur_node.neighbors:
if neighbor in closedSet:
continue
if neighbor not in openSet:
openSet.append(neighbor)
if neighbor.gScore >= cur_node.gScore:
print(neighbor.gScore)
print(cur_node.gScore)
continue # this is not eh better path
# this path is the best for now, so record it
neighbor.cameFrom = cur_node
print(cur_node)
printMap(cur_node.location)
def reconstruct(target):
path = []
while target:
print("here")
path.append(target.location)
target = target.cameFrom
return path
For those commenting that this is a duplicate: yeah it is. I'm not getting a response on the old post, so I edited it and reposted. I will delete the old post.

Python, calculating family tree depth from one member to another

I have a dictionary with family tree data(key - name of a person, it's value - children).
I'd like to recursively get a depth from one given member to another (get_depth(from_person, to_person)).
I would choose DFS, since it makes keeping track of the depth easy.
def get_depth(root, target):
if root == target:
return 0
if not d[root]:
return None
for child in d[root]:
depth = get_depth(child, target)
if depth is not None:
return 1 + depth
return None
The last return is strictly speaking unnecessary, but I prefer to spell these things out. Feel free to ask any questions, but this should be fairly self-explanatory. You might feel more comfortable replacing None with -1 and then checking if depth >= 0

Perfect Binary Tree with correct data

I am having a problem trying to fill the data a perfect binary tree with a known number of nodes with the correct data. Basically, I have an implementation that creates this:
7
5 6
1 2 3 4
However, I am looking to create a tree like this:
7
3 6
1 2 4 5
My current implementation for inserting the nodes of a tree is as follows.
def _add_node(self, val, ref = None):
# reference to root of tree
ref = self.root if ref is None else ref
if ref.right is None:
ref.right = Node(val, ref)
return
elif ref.left is None:
ref.left = Node(val, ref)
return
else:
parent = (val - 1) / 2
if parent % 2 == 0:
self._add_node(val, ref.left)
else:
self._add_node(val, ref.right)
Given x nodes I create a tree using range(x) and calling add_node(i) for each iteration. This works fine except its order is incorrect.
For the life of me I cannot figure out an easy way to set the values to represent the bottom layout rather than the top. Can anyone help me out?
This seems to be an issue with the order that you are entering data in. How are you passing in the data?
Also think about your implementation. You check to see whether the right child is empty and if it is you place the node there. However, if it isn't you move on to the left node. This is where the issue is happening.
Assuming you are passing in the data in reverse chronological order you start with 7 at the root. Then you move to 6 which you place in the right node. Then move on to 5; you check to see whether the right node is empty, which is isn't because it is filled with 6, so you move on to check if the left node is empty and find that it is. So you place 5 there.
Do you see the issue?
You need to figure out a way to get around this issue, but hopefully this was good in helping you debug.
Good Luck!

Categories