I'm new to python and am trying to return the preorder list of an ordered tree (NOTE: Not Binary Tree). I'm having some trouble following the recursion after it reaches a leaf of the tree. How do I get it to go back up to the previous node? Here's my code thus far:
def OrdPreOrder(T):
if Is_OrdLeaf(T):
return []
else:
for t in Subtrees(T):
return [OrdRoot(t)] + OrdPreOrder(t)
Thanks in advance,
The question is not very clear to me, but hopefully this will help.
You want to do a pre-order traversal of an ordered tree.
Pre-Order traversal means
1. Firstly print the value stored in node
2. Then print the value stored in children (according to some principle)
First off,
How do I get it to go back up to the previous node?
According to the definition of pre-order traversal i have written above, I don't see why you need to go back and revisit the parent node.
class Node:
def __init__(self, data):
self.__data = data
self.__children = []
def identifier(self):
return self.__data
def children(self):
return self.__children
def add_child(self, data):
self.__children.append(data)
class Tree:
def __init__(self):
self.__nodes = {}
def nodes(self):
return self.__nodes
def add_node(self, data, parent=None):
node = Node(data)
self[data] = node
if parent is not None:
self[parent].add_child(data)
return node
def traversal(tree):
if tree == None:
return
print (tree.identifier())
for child in tree.children():
traversal(child)
I am also not that well versed with data structures in Python (there might be mistakes in the code). But hopefully it might point you in the right direction.
Related
I am writing a function to solve the following problem:
"Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level).
e.g. Input: root = [3,9,20,null,null,15,7]
Output: [[3],[9,20],[15,7]]
"
Here is my code:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrder(self, root: TreeNode):
queue = deque([root])
output = []
if not root:
return output
while queue:
root = queue.popleft()
output.append(root.val)
queue.append(root.left)
queue.append(root.right)
return output
I seem to be getting the error: "Nonetype has no attribute val" for the line output.append(root.val). Any ideas why?
I thought I covered the edge case when root is empty.
P.S. I know my code doesn't solve the problem, as it doesn't address the 'level's by not separating each level into different arrays.
But I want to just see if my code traverses the tree in the correct order first!
I am too stupid to ask a question. A lot of literature mentioned that we need to compare the to-insert value with the value of "current Node".
So basically, my question is:
In order to insert a new Node into a tree, we need to enter a Node. Firstly, the tree has to check whether this Node is in it. If yes, then we need to enter a value, which will be compared and then inserted.
class BTree:
def __init__(self):
self.root = None
def isEmpty(self):
if not self.root:
print('tree is empty')
return self.root
def insert(self, Node, data):
if not self.isEmpty():
print('the tree is empty, now is inserting ROOT')
self.root = Node(data)
else:
current = self.root
parent = None
while True:
#search the Node in the tree#
#if it is in the tree, insert#
It is too complicated, isn't it? Because we need even implement the search algorithm in the while loop.
Could you please give me some suggestions?
Thanks
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!
Please help me to understand trees in Python. This is an example of tree implementation I found in the Internet.
from collections import deque
class EmptyTree(object):
"""Represents an empty tree."""
# Supported methods
def isEmpty(self):
return True
def __str__(self):
return ""
def __iter__(self):
"""Iterator for the tree."""
return iter([])
def preorder(self, lyst):
return
def inorder(self, lyst):
return
def postorder(self, lyst):
return
class BinaryTree(object):
"""Represents a nonempty binary tree."""
# Singleton for all empty tree objects
THE_EMPTY_TREE = EmptyTree()
def __init__(self, item):
"""Creates a tree with
the given item at the root."""
self._root = item
self._left = BinaryTree.THE_EMPTY_TREE
self._right = BinaryTree.THE_EMPTY_TREE
def isEmpty(self):
return False
def getRoot(self):
return self._root
def getLeft(self):
return self._left
def getRight(self):
return self._right
def setRoot(self, item):
self._root = item
def setLeft(self, tree):
self._left = tree
def setRight(self, tree):
self._right = tree
def removeLeft(self):
left = self._left
self._left = BinaryTree.THE_EMPTY_TREE
return left
def removeRight(self):
right = self._right
self._right = BinaryTree.THE_EMPTY_TREE
return right
def __str__(self):
"""Returns a string representation of the tree
rotated 90 degrees to the left."""
def strHelper(tree, level):
result = ""
if not tree.isEmpty():
result += strHelper(tree.getRight(), level + 1)
result += " " * level
result += str(tree.getRoot()) + "\n"
result += strHelper(tree.getLeft(), level + 1)
return result
return strHelper(self, 0)
def __iter__(self):
"""Iterator for the tree."""
lyst = []
self.inorder(lyst)
return iter(lyst)
def preorder(self, lyst):
"""Adds items to lyst during
a preorder traversal."""
lyst.append(self.getRoot())
self.getLeft().preorder(lyst)
self.getRight().preorder(lyst)
def inorder(self, lyst):
"""Adds items to lyst during
an inorder traversal."""
self.getLeft().inorder(lyst)
lyst.append(self.getRoot())
self.getRight().inorder(lyst)
def postorder(self, lyst):
"""Adds items to lystduring
a postorder traversal."""
self.getLeft().postorder(lyst)
self.getRight().postorder(lyst)
lyst.append(self.getRoot())
def levelorder(self, lyst):
"""Adds items to lyst during
a levelorder traversal."""
# levelsQueue = LinkedQueue()
levelsQueue = deque ([])
levelsQueue.append(self)
while levelsQueue != deque():
node = levelsQueue.popleft()
lyst.append(node.getRoot())
left = node.getLeft()
right = node.getRight()
if not left.isEmpty():
levelsQueue.append(left)
if not right.isEmpty():
levelsQueue.append(right)
This is programm that makes the small tree.
"""
File: testbinarytree.py
Builds a full binary tree with 7 nodes.
"""
from binarytree import BinaryTree
lst = ["5", "+", "2"]
for i in range(len(lst)):
b = BinaryTree(lst[0])
d = BinaryTree(lst[1])
f = BinaryTree(lst[2])
# Build the tree from the bottom up, where
# d is the root node of the entire tree
d.setLeft(b)
d.setRight(f)
def size(tree):
if tree.isEmpty():
return 0
else:
return 1 + size(tree.getLeft()) + size(tree.getRight())
def frontier(tree):
"""Returns a list containing the leaf nodes
of tree."""
if tree.isEmpty():
return []
elif tree.getLeft().isEmpty() and tree.getRight().isEmpty():
return [tree.getRoot()]
else:
return frontier(tree.getLeft()) + frontier(tree.getRight())
print ("Size:", size(d))
print ("String:")
print (d)
How can I make a class that will count the value of the expression, such that the answer = 7 (5+2). I really want to understand the concept with a small example.
It sounds like your problem isn't trees, which are a much more general (and simple) concept, but in how to properly populate and/or evaluate an expression tree.
If you have your operators specified in post-fix order, it becomes a lot easier.
See this wikipedia article on how to deal with infix notation when parsing input to a desktop calculator. It is called the shunting-yard algorithm.
You should do function that walks a tree in depth first order, calculating value of each node, either just taking value of it (if it is "5" for example), or making calculation (if it is "+" for example) - by walking the tree in depth first order you are sure that all subnodes of given node will be calculated when you are calculating that node (for example "5" and "2" will be calculated when you are calculating "+").
Then, at the root of the tree you'll get the result of the whole tree.
First of all, I'm not going to give much detail in case this is homework, which it sounds a bit like.
You need a method on your tree class that evaluates the tree. I suppose it'll assume that the "root" value of each tree node is a number (when the node is a leaf, i.e. when it has no children) or the name of an operator (When the node has children).
Your method will be recursive: the value of a tree-node with children is determined by (1) the value of its left subtree, (2) the value of its right subtree, and (3) the operator in its "root".
You'll probably want a table -- maybe stored in a dict -- mapping operator names like "+" to actual functions like operator.add (or, if you prefer, lambda x,y: x+y).