In the given tree when we pass node-- 2 then output is 5, it counts all the nodes after 2,
4-5-6-7-8
def count(node):
if node is None:
return 0
return 1+count(node.lchild)+count(node.rchild)
but with this, I only count its child nodes
As others have said, your code is designed for node instances that have lchild and rchild members, but the tree in the picture has a node with 3 children, so it cannot be represented as such a node.
You need a different definition of your Node class:
class Node:
def __init__(self, value, *children):
self.value = value
self.children = children
Then I would define count as a method of that class, not as a stand-alone function:
class Node
# ...
def count(self):
return sum(1 + child.count() for child in self.children)
Example run:
# Create the tree as pictured in the question
root = Node(1,
Node(2,
Node(4),
Node(5,
Node(7),
Node(8)
),
Node(6)),
Node(3)
)
# Select the node with value 2 (at left of root) and call the `count` method:
print(root.children[0].count())
Your code runs correctly on Binary Tree but the Tree of your question is not Binary Tree, you need a different approach. You need to define list of child for every node in your class and use this code:
def count(node):
if node is None:
return 0
count = 1
for child in node_child
count += count(child)
return count
Related
I am trying to write a logic to insert a node into a binary tree.
The node looks like this
class BinTree:
def __init__(self, Id):
self.Id = Id
self.NodeCounter = 1
self.left = None
self.right = None
I need to insert a new node only if it doesnt exist in the tree but increment the counter if it exists already.
As of now, what im doing is whenever i get a new element to insert, i first search it in the binary tree, if the node is found i increment the NodeCounter by 1, otherwise I again start traversing from root node and then go and insert the new node
The problem here is that for every new node, i am traversing the tree twice which i dont want… And when i am trying to search and insert at the same time,the counters get messed because of recursion.
Is there a way I can achieve this?
Any tips would be appreciated
i first search it in the binary tree
...this would only be an efficient process if your binary tree is a binary search tree (BST). I'll assume that is what we are talking about.
if the node is found i increment the NodeCounter by 1, otherwise I again start traversing from root node and then go and insert the new node
Why would you start from the root again? When you did the search and didn't find the node, there was a last node that you visited. Just attach the new node to it.
Here is a possible implementation:
class Node:
def __init__(self, id):
self.id = id
self.nodeCounter = 1
self.left = None
self.right = None
class BinTree:
def __init__(self):
self.root = None
def add(self, id):
self.root = self.addrecur(self.root, id)
def addrecur(self, node, id):
if not node:
node = Node(id)
elif id == node.id:
node.nodeCounter += 1
elif id < node.id:
node.left = self.addrecur(node.left, id)
else:
node.right = self.addrecur(node.right, id)
return node
def __repr__(self):
return self.indented(self.root)
def indented(self, node, indent=""):
if not node:
return ""
return (self.indented(node.right, indent + " ")
+ f"{indent}{node.id} ({node.nodeCounter})\n"
+ self.indented(node.left, indent + " "))
tree = BinTree()
tree.add(4)
tree.add(2)
tree.add(3)
tree.add(2)
tree.add(6)
tree.add(5)
tree.add(5)
print(tree)
This outputs the tree in side-ways view (root at left) with the node count in parentheses:
6 (1)
5 (2)
4 (1)
3 (1)
2 (2)
You will be adding to the classes Node and Tree that we developed in our lectures. There are several short methods that you will have to write.
Write a method is_similar() that takes as input two binary trees and returns true if the nodes have the same key values and are arranged in the same order and false otherwise.
def is_similar (self, pNode):
Write a method print_level() that takes as input the level and prints out all the nodes at that level. If that level does not exist for that binary search tree it prints nothing. Use the convention that the root is at level 1.
def print_level (self, level):
Write a method get_height() that returns the height of a binary tree. Recall that the height of a tree is the longest path length from the root to a leaf.
def get_height (self):
Write a method num_nodes() that returns the number of nodes in the left subtree from the root and the number of nodes in the right subtree from the root and the root itself. This function will be useful to determine if the tree is balanced.
def num_nodes (self):
Input: The input will read from a file. The file will be formatted as follows:
Line 1: Several integers separated by spaces to be inserted into Tree 1
Line 2: Several integers separated by spaces to be inserted into Tree 2
You will read both lines of data. Create two Trees and insert the integers in the order given. Then you will use these two trees to test the methods that you have written.
Output: The output will be formatted as follows:
The Trees are similar: (True or False)
Levels of Tree 1:
print each level on its own line
Levels of Tree 2:
print each level on its own line
Height of Tree 1:
Nodes in Tree 1:
Height of Tree 2:
Nodes in Tree 2:
For example, given the following input file:
14 17 1
14 17 1
This would be the output:
The Trees are similare: True
Levels of Tree 1:
14
1 17
Levels of Tree 2:
14
1 17
Height of Tree 1: 1
Nodes in Tree 1: 3
Height of Tree 2: 1
Nodes in Tree 2: 3
You will be writing helper methods for the Tree class that we developed. The following is the outline of the code that you will be submitting. You may include other functions that we developed for completeness. You may add helper functions as needed.
Below is the code that I need help finishing. Not entirely sure how to start the helper functions or main so any help would be appreciated.
import os
class Node (object):
def __init__ (self, data):
self.data = data
self.lchild = None
self.rchild = None
class Tree (object):
def __init__ (self):
self.root = None
# insert data into the tree
def insert (self, data):
new_node = Node (data)
if (self.root == None):
self.root = new_node
return
else:
current = self.root
parent = self.root
while (current != None):
parent = current
if (data < current.data):
current = current.lchild
else:
current = current.rchild
# found location now insert node
if (data < parent.data):
parent.lchild = new_node
else:
parent.rchild = new_node
# Returns true if two binary trees are similar
def is_similar (self, pNode):
pass
# Prints out all nodes at the given level
def print_level (self, level):
pass
# Returns the height of the tree
def get_height (self):
pass
# Returns the number of nodes in tree which is
# equivalent to 1 + number of nodes in the left
# subtree + number of nodes in the right subtree
def num_nodes (self):
pass
def main():
# write code here
main()
As a hint, think of how you would need to traverse the binary tree in the implementation of each helper method.
For num_nodes, I am not sure what "and the number of nodes in the right subtree from the root and the root itself." means. Should we return the number of nodes in the right subtree + 1?
#classmethod
def count_below(node):
count=0
if (node == None):
return 0 # if one of the root's childs was None
if (node.lchild == None and node.rchild == None): # leaf
return 1 # base case
if (node.lchild != None):
count+=count_below(node.lchild)
if (node.rchild != None):
count+=count_below(node.rchild)
return count
def num_nodes(self):
if (self.root == None):
return 0
return count_below(self.root.lchild), count_below(self.root.rchild) + 1
#classmethod
def depth_below(node):
if node is None:
return 0 # base case
# Compute the depth of each subtree
ldepth = depth_below(node.lchild) # recurse left
rdepth = depth_below(node.rchild) # recurse right
# once all the recursive calls performed on this node's childs resolve
# return the depth of the subtree of this node with the greater depth
if (ldepth > rdepth):
return ldepth+1
else:
return rdepth+1
def get_height(self):
return depth_below(self.root) # depth from root
#classmethod
def explore_childs(node, current_level, target_level):
if (node.lchild==None and node.rchild==None):
return # base case
if (current_level == target_level):
if (node.lchild!=None):
print(node.lchild.data)
if (node.rchild!=None):
print(node.rchild.data)
return # base case
if (node.lchild!=None):
explore_childs(node.lchild, current_level+1, target_level) # recurse left
if (node.rchild!=None):
explore_childs(node.rchild, current_level+1, target_level) # recurse right
def print_level(self, level):
if (level > self.get_height()):
pass # throw error
explore_childs(root, 0, level)
I'm trying to construct a tree in Python that can take 4 children. The children are defined as an array.
What I'm struggling with is inserting recursively into this tree.
Here is what I've done so far:
Node Class:
class node:
def __init__(self,value,city,children=[None,None,None,None]):
self.value = value
self.children = children
self.city = city
Tree Class:
from node import *
from isFull import *
class tree:
root = None
def __int__(self):
self.root = None
def insert(self, city, value):
if self.root == None:
self.root = node(value, city, children=[None,None,None,None])
else:
self.rec_insert(city, value, self.root, 0)
def rec_insert(self, city, value, nodes, index):
if nodes.children[index] is None:
nodes.children[index] = node(value, city, children=[None,None,None,None])
return
elif index < 3:
self.rec_insert(city, value, nodes, index + 1)
elif index == 3:
self.rec_insert(city, value, nodes.children[0], 0)
So what I have observed is that this first if statement actually works. I can insert a root and into the first layer of children.
if nodes.children[index] is None:
Now the problem arises in level 2. Probably because I'm descending wrong.
At the start I can insert normally into layer 2, however as it gets to the right side of the tree it skips the last child in layer 2.
My logic behind this function:
self.rec_insert(city, value, nodes.children[0], 0)
I wanted to make it descend just into the left most child then my other conditional statements will make it shift right as it inserts.
This check:
elif index == 3:
I use it to determine if all the children have been inserted into in a node.
Any help will be appreciated.
I have created a Tree structure that is not a binary tree and having difficulties in getting the correct node count.
class TreeNode(object):
def __init__(self, name='root', children=None,Parent=[]):
self.Name = name
self.Parents=Parent
self.Children = []
if children is not None:
for child in children:
self.add_child(child.Name)
def __repr__(self):
return self.Name
def add_child(self, node):
self.Children.append(node)
and this is the latest in what I have tried to do in order to count the number of nodes in the tree.
def countNodes(Tree):
for Child in Tree.Children:
return countNodes(Child)+1
return 1
Could someone explain why this doesn't work?
EDIT: I should clarify, When I say doesn't work it gives me a completely wrong count for he number of nodes in my graph.
You countNodes function is not well. A parent node can have two childs, if you put a return statement within the for loop, it will return on the first child count and the second child count will be missing. You need to do something like this:
def countNodes(Tree):
count = 1
for Child in Tree.Children:
count += countNodes(Child)
return count
Just to add #levi has missed an edge case where root is None
so the modified code will be :
def numNodes(root):
if root == None:
return 0
node = 1
for child in root.children:
node = node + numNodes(child)
return node
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!