Recursively Creating a Binary Tree Given a String Expression in Prefix Notation in Python
Representation of LinkedBinaryTree that should be outputted
import LinkedBinaryTree
def create_expression_tree(prefix_exp_str):
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
op = ['+', '-', '*', '/']
elem = prefix_exp[start_pos]
if elem == ' ':
elem = prefix_exp[start_pos+1]
start_pos += 1
if elem not in op:
return LinkedBinaryTree.LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
right = create_expression_tree_helper(prefix_exp, start_pos+2)
return LinkedBinaryTree.LinkedBinaryTree.Node(elem, left, right)
tree = LinkedBinaryTree.LinkedBinaryTree(create_expression_tree_helper(prefix_exp_str, -1))
return tree
tree1 = create_expression_tree('* 2 + - 15 6 4')
for i in tree1.preorder():
print(i.data, end='')
I implemented my own binary tree class which is shown below. Preorder() is a generator for my LinkedBinaryTree that gives the values of the tree in prefix order. With this code, I'm outputting
*2+-151
but it should be outputting
*2+-1564 if the binary expression tree has been created correctly.
I'm aware that there is an issue with numbers greater than 1 digit, but I'm not sure how to fix it without compromising the runtime (ie. using slicing). Also I'm not sure why it is omitting some of the tokens. Any ideas? (The implementation must run in linear time and use no additional parameters in the helper function I've defined).
import ArrayQueue
class LinkedBinaryTree:
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
def __init__(self, root=None):
self.root = root
self.size = self.subtree_count(root)
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
def subtree_count(self, root):
if (root is None):
return 0
else:
left_count = self.subtree_count(root.left)
right_count = self.subtree_count(root.right)
return 1 + left_count + right_count
def sum(self):
return self.subtree_sum(self.root)
def subtree_sum(self, root):
if (root is None):
return 0
else:
left_sum = self.subtree_sum(root.left)
right_sum = self.subtree_sum(root.right)
return root.data + left_sum + right_sum
def height(self):
return self.subtree_height(self.root)
def subtree_height(self, root):
if (root.left is None and root.right is None):
return 0
elif (root.left is None):
return 1 + self.subtree_height(root.right)
elif (root.right is None):
return 1 + self.subtree_height(root.left)
else:
left_height = self.subtree_height(root.left)
right_height = self.subtree_height(root.right)
return 1 + max(left_height, right_height)
def preorder(self):
yield from self.subtree_preorder(self.root)
def subtree_preorder(self, root):
if(root is None):
return
else:
yield root
yield from self.subtree_preorder(root.left)
yield from self.subtree_preorder(root.right)
def postorder(self):
yield from self.subtree_postorder(self.root)
def subtree_postorder(self, root):
if(root is None):
return
else:
yield from self.subtree_postorder(root.left)
yield from self.subtree_postorder(root.right)
yield root
def inorder(self):
yield from self.subtree_inorder(self.root)
def subtree_inorder(self, root):
if(root is None):
return
else:
yield from self.subtree_inorder(root.left)
yield root
yield from self.subtree_inorder(root.right)
def breadth_first(self):
if (self.is_empty()):
return
line = ArrayQueue.ArrayQueue()
line.enqueue(self.root)
while (line.is_empty() == False):
curr_node = line.dequeue()
yield curr_node
if (curr_node.left is not None):
line.enqueue(curr_node.left)
if (curr_node.right is not None):
line.enqueue(curr_node.right)
def __iter__(self):
for node in self.breadth_first():
yield node.data
I added the code here for LinkedBinaryTree class. The ArrayQueue class that is used in the implementation of the breadth traversal method is just a basic queue using a Python list as the underlying data structure.
python recursion binary-tree prefix
|
show 2 more comments
Representation of LinkedBinaryTree that should be outputted
import LinkedBinaryTree
def create_expression_tree(prefix_exp_str):
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
op = ['+', '-', '*', '/']
elem = prefix_exp[start_pos]
if elem == ' ':
elem = prefix_exp[start_pos+1]
start_pos += 1
if elem not in op:
return LinkedBinaryTree.LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
right = create_expression_tree_helper(prefix_exp, start_pos+2)
return LinkedBinaryTree.LinkedBinaryTree.Node(elem, left, right)
tree = LinkedBinaryTree.LinkedBinaryTree(create_expression_tree_helper(prefix_exp_str, -1))
return tree
tree1 = create_expression_tree('* 2 + - 15 6 4')
for i in tree1.preorder():
print(i.data, end='')
I implemented my own binary tree class which is shown below. Preorder() is a generator for my LinkedBinaryTree that gives the values of the tree in prefix order. With this code, I'm outputting
*2+-151
but it should be outputting
*2+-1564 if the binary expression tree has been created correctly.
I'm aware that there is an issue with numbers greater than 1 digit, but I'm not sure how to fix it without compromising the runtime (ie. using slicing). Also I'm not sure why it is omitting some of the tokens. Any ideas? (The implementation must run in linear time and use no additional parameters in the helper function I've defined).
import ArrayQueue
class LinkedBinaryTree:
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
def __init__(self, root=None):
self.root = root
self.size = self.subtree_count(root)
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
def subtree_count(self, root):
if (root is None):
return 0
else:
left_count = self.subtree_count(root.left)
right_count = self.subtree_count(root.right)
return 1 + left_count + right_count
def sum(self):
return self.subtree_sum(self.root)
def subtree_sum(self, root):
if (root is None):
return 0
else:
left_sum = self.subtree_sum(root.left)
right_sum = self.subtree_sum(root.right)
return root.data + left_sum + right_sum
def height(self):
return self.subtree_height(self.root)
def subtree_height(self, root):
if (root.left is None and root.right is None):
return 0
elif (root.left is None):
return 1 + self.subtree_height(root.right)
elif (root.right is None):
return 1 + self.subtree_height(root.left)
else:
left_height = self.subtree_height(root.left)
right_height = self.subtree_height(root.right)
return 1 + max(left_height, right_height)
def preorder(self):
yield from self.subtree_preorder(self.root)
def subtree_preorder(self, root):
if(root is None):
return
else:
yield root
yield from self.subtree_preorder(root.left)
yield from self.subtree_preorder(root.right)
def postorder(self):
yield from self.subtree_postorder(self.root)
def subtree_postorder(self, root):
if(root is None):
return
else:
yield from self.subtree_postorder(root.left)
yield from self.subtree_postorder(root.right)
yield root
def inorder(self):
yield from self.subtree_inorder(self.root)
def subtree_inorder(self, root):
if(root is None):
return
else:
yield from self.subtree_inorder(root.left)
yield root
yield from self.subtree_inorder(root.right)
def breadth_first(self):
if (self.is_empty()):
return
line = ArrayQueue.ArrayQueue()
line.enqueue(self.root)
while (line.is_empty() == False):
curr_node = line.dequeue()
yield curr_node
if (curr_node.left is not None):
line.enqueue(curr_node.left)
if (curr_node.right is not None):
line.enqueue(curr_node.right)
def __iter__(self):
for node in self.breadth_first():
yield node.data
I added the code here for LinkedBinaryTree class. The ArrayQueue class that is used in the implementation of the breadth traversal method is just a basic queue using a Python list as the underlying data structure.
python recursion binary-tree prefix
1
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to yourLinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.
– Silmathoron
Nov 24 '18 at 10:11
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30
|
show 2 more comments
Representation of LinkedBinaryTree that should be outputted
import LinkedBinaryTree
def create_expression_tree(prefix_exp_str):
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
op = ['+', '-', '*', '/']
elem = prefix_exp[start_pos]
if elem == ' ':
elem = prefix_exp[start_pos+1]
start_pos += 1
if elem not in op:
return LinkedBinaryTree.LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
right = create_expression_tree_helper(prefix_exp, start_pos+2)
return LinkedBinaryTree.LinkedBinaryTree.Node(elem, left, right)
tree = LinkedBinaryTree.LinkedBinaryTree(create_expression_tree_helper(prefix_exp_str, -1))
return tree
tree1 = create_expression_tree('* 2 + - 15 6 4')
for i in tree1.preorder():
print(i.data, end='')
I implemented my own binary tree class which is shown below. Preorder() is a generator for my LinkedBinaryTree that gives the values of the tree in prefix order. With this code, I'm outputting
*2+-151
but it should be outputting
*2+-1564 if the binary expression tree has been created correctly.
I'm aware that there is an issue with numbers greater than 1 digit, but I'm not sure how to fix it without compromising the runtime (ie. using slicing). Also I'm not sure why it is omitting some of the tokens. Any ideas? (The implementation must run in linear time and use no additional parameters in the helper function I've defined).
import ArrayQueue
class LinkedBinaryTree:
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
def __init__(self, root=None):
self.root = root
self.size = self.subtree_count(root)
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
def subtree_count(self, root):
if (root is None):
return 0
else:
left_count = self.subtree_count(root.left)
right_count = self.subtree_count(root.right)
return 1 + left_count + right_count
def sum(self):
return self.subtree_sum(self.root)
def subtree_sum(self, root):
if (root is None):
return 0
else:
left_sum = self.subtree_sum(root.left)
right_sum = self.subtree_sum(root.right)
return root.data + left_sum + right_sum
def height(self):
return self.subtree_height(self.root)
def subtree_height(self, root):
if (root.left is None and root.right is None):
return 0
elif (root.left is None):
return 1 + self.subtree_height(root.right)
elif (root.right is None):
return 1 + self.subtree_height(root.left)
else:
left_height = self.subtree_height(root.left)
right_height = self.subtree_height(root.right)
return 1 + max(left_height, right_height)
def preorder(self):
yield from self.subtree_preorder(self.root)
def subtree_preorder(self, root):
if(root is None):
return
else:
yield root
yield from self.subtree_preorder(root.left)
yield from self.subtree_preorder(root.right)
def postorder(self):
yield from self.subtree_postorder(self.root)
def subtree_postorder(self, root):
if(root is None):
return
else:
yield from self.subtree_postorder(root.left)
yield from self.subtree_postorder(root.right)
yield root
def inorder(self):
yield from self.subtree_inorder(self.root)
def subtree_inorder(self, root):
if(root is None):
return
else:
yield from self.subtree_inorder(root.left)
yield root
yield from self.subtree_inorder(root.right)
def breadth_first(self):
if (self.is_empty()):
return
line = ArrayQueue.ArrayQueue()
line.enqueue(self.root)
while (line.is_empty() == False):
curr_node = line.dequeue()
yield curr_node
if (curr_node.left is not None):
line.enqueue(curr_node.left)
if (curr_node.right is not None):
line.enqueue(curr_node.right)
def __iter__(self):
for node in self.breadth_first():
yield node.data
I added the code here for LinkedBinaryTree class. The ArrayQueue class that is used in the implementation of the breadth traversal method is just a basic queue using a Python list as the underlying data structure.
python recursion binary-tree prefix
Representation of LinkedBinaryTree that should be outputted
import LinkedBinaryTree
def create_expression_tree(prefix_exp_str):
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
op = ['+', '-', '*', '/']
elem = prefix_exp[start_pos]
if elem == ' ':
elem = prefix_exp[start_pos+1]
start_pos += 1
if elem not in op:
return LinkedBinaryTree.LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
right = create_expression_tree_helper(prefix_exp, start_pos+2)
return LinkedBinaryTree.LinkedBinaryTree.Node(elem, left, right)
tree = LinkedBinaryTree.LinkedBinaryTree(create_expression_tree_helper(prefix_exp_str, -1))
return tree
tree1 = create_expression_tree('* 2 + - 15 6 4')
for i in tree1.preorder():
print(i.data, end='')
I implemented my own binary tree class which is shown below. Preorder() is a generator for my LinkedBinaryTree that gives the values of the tree in prefix order. With this code, I'm outputting
*2+-151
but it should be outputting
*2+-1564 if the binary expression tree has been created correctly.
I'm aware that there is an issue with numbers greater than 1 digit, but I'm not sure how to fix it without compromising the runtime (ie. using slicing). Also I'm not sure why it is omitting some of the tokens. Any ideas? (The implementation must run in linear time and use no additional parameters in the helper function I've defined).
import ArrayQueue
class LinkedBinaryTree:
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
def __init__(self, root=None):
self.root = root
self.size = self.subtree_count(root)
def __len__(self):
return self.size
def is_empty(self):
return len(self) == 0
def subtree_count(self, root):
if (root is None):
return 0
else:
left_count = self.subtree_count(root.left)
right_count = self.subtree_count(root.right)
return 1 + left_count + right_count
def sum(self):
return self.subtree_sum(self.root)
def subtree_sum(self, root):
if (root is None):
return 0
else:
left_sum = self.subtree_sum(root.left)
right_sum = self.subtree_sum(root.right)
return root.data + left_sum + right_sum
def height(self):
return self.subtree_height(self.root)
def subtree_height(self, root):
if (root.left is None and root.right is None):
return 0
elif (root.left is None):
return 1 + self.subtree_height(root.right)
elif (root.right is None):
return 1 + self.subtree_height(root.left)
else:
left_height = self.subtree_height(root.left)
right_height = self.subtree_height(root.right)
return 1 + max(left_height, right_height)
def preorder(self):
yield from self.subtree_preorder(self.root)
def subtree_preorder(self, root):
if(root is None):
return
else:
yield root
yield from self.subtree_preorder(root.left)
yield from self.subtree_preorder(root.right)
def postorder(self):
yield from self.subtree_postorder(self.root)
def subtree_postorder(self, root):
if(root is None):
return
else:
yield from self.subtree_postorder(root.left)
yield from self.subtree_postorder(root.right)
yield root
def inorder(self):
yield from self.subtree_inorder(self.root)
def subtree_inorder(self, root):
if(root is None):
return
else:
yield from self.subtree_inorder(root.left)
yield root
yield from self.subtree_inorder(root.right)
def breadth_first(self):
if (self.is_empty()):
return
line = ArrayQueue.ArrayQueue()
line.enqueue(self.root)
while (line.is_empty() == False):
curr_node = line.dequeue()
yield curr_node
if (curr_node.left is not None):
line.enqueue(curr_node.left)
if (curr_node.right is not None):
line.enqueue(curr_node.right)
def __iter__(self):
for node in self.breadth_first():
yield node.data
I added the code here for LinkedBinaryTree class. The ArrayQueue class that is used in the implementation of the breadth traversal method is just a basic queue using a Python list as the underlying data structure.
python recursion binary-tree prefix
python recursion binary-tree prefix
edited Nov 24 '18 at 20:36
Kevin Chang
asked Nov 23 '18 at 23:57
Kevin ChangKevin Chang
83
83
1
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to yourLinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.
– Silmathoron
Nov 24 '18 at 10:11
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30
|
show 2 more comments
1
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to yourLinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.
– Silmathoron
Nov 24 '18 at 10:11
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30
1
1
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to your
LinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.– Silmathoron
Nov 24 '18 at 10:11
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to your
LinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.– Silmathoron
Nov 24 '18 at 10:11
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30
|
show 2 more comments
1 Answer
1
active
oldest
votes
The two issues with your code were:
- you processed the characters one by one while several-digit numbers could be present (fixed by splitting the expression to a list)
- you did not account for the fact that chained operator expressions could be longer that just your standard increment (fixed by adding a
size
property toNode
So here is the new Node
class
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
@property
def size(self):
l = 1
if self.left is not None:
l += self.left.size
if self.right is not None:
l += self.right.size
return l
and here is the new tree creator
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
incr = left.size
right = create_expression_tree_helper(prefix_exp, start_pos+incr)
node = LinkedBinaryTree.Node(elem, left, right)
return node
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1))
return tree
EDIT here is a version that does not require to modify the Node
class
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
size = 1
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left, left_size = create_expression_tree_helper(prefix_exp, start_pos)
right, right_size = create_expression_tree_helper(prefix_exp, start_pos+left_size)
node = LinkedBinaryTree.Node(elem, left, right)
size += left_size + right_size
return node, size
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1)[0])
return tree
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454035%2frecursively-creating-a-binary-tree-given-a-string-expression-in-prefix-notation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The two issues with your code were:
- you processed the characters one by one while several-digit numbers could be present (fixed by splitting the expression to a list)
- you did not account for the fact that chained operator expressions could be longer that just your standard increment (fixed by adding a
size
property toNode
So here is the new Node
class
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
@property
def size(self):
l = 1
if self.left is not None:
l += self.left.size
if self.right is not None:
l += self.right.size
return l
and here is the new tree creator
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
incr = left.size
right = create_expression_tree_helper(prefix_exp, start_pos+incr)
node = LinkedBinaryTree.Node(elem, left, right)
return node
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1))
return tree
EDIT here is a version that does not require to modify the Node
class
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
size = 1
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left, left_size = create_expression_tree_helper(prefix_exp, start_pos)
right, right_size = create_expression_tree_helper(prefix_exp, start_pos+left_size)
node = LinkedBinaryTree.Node(elem, left, right)
size += left_size + right_size
return node, size
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1)[0])
return tree
add a comment |
The two issues with your code were:
- you processed the characters one by one while several-digit numbers could be present (fixed by splitting the expression to a list)
- you did not account for the fact that chained operator expressions could be longer that just your standard increment (fixed by adding a
size
property toNode
So here is the new Node
class
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
@property
def size(self):
l = 1
if self.left is not None:
l += self.left.size
if self.right is not None:
l += self.right.size
return l
and here is the new tree creator
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
incr = left.size
right = create_expression_tree_helper(prefix_exp, start_pos+incr)
node = LinkedBinaryTree.Node(elem, left, right)
return node
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1))
return tree
EDIT here is a version that does not require to modify the Node
class
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
size = 1
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left, left_size = create_expression_tree_helper(prefix_exp, start_pos)
right, right_size = create_expression_tree_helper(prefix_exp, start_pos+left_size)
node = LinkedBinaryTree.Node(elem, left, right)
size += left_size + right_size
return node, size
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1)[0])
return tree
add a comment |
The two issues with your code were:
- you processed the characters one by one while several-digit numbers could be present (fixed by splitting the expression to a list)
- you did not account for the fact that chained operator expressions could be longer that just your standard increment (fixed by adding a
size
property toNode
So here is the new Node
class
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
@property
def size(self):
l = 1
if self.left is not None:
l += self.left.size
if self.right is not None:
l += self.right.size
return l
and here is the new tree creator
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
incr = left.size
right = create_expression_tree_helper(prefix_exp, start_pos+incr)
node = LinkedBinaryTree.Node(elem, left, right)
return node
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1))
return tree
EDIT here is a version that does not require to modify the Node
class
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
size = 1
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left, left_size = create_expression_tree_helper(prefix_exp, start_pos)
right, right_size = create_expression_tree_helper(prefix_exp, start_pos+left_size)
node = LinkedBinaryTree.Node(elem, left, right)
size += left_size + right_size
return node, size
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1)[0])
return tree
The two issues with your code were:
- you processed the characters one by one while several-digit numbers could be present (fixed by splitting the expression to a list)
- you did not account for the fact that chained operator expressions could be longer that just your standard increment (fixed by adding a
size
property toNode
So here is the new Node
class
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.parent = None
self.left = left
if (self.left is not None):
self.left.parent = self
self.right = right
if (self.right is not None):
self.right.parent = self
@property
def size(self):
l = 1
if self.left is not None:
l += self.left.size
if self.right is not None:
l += self.right.size
return l
and here is the new tree creator
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left = create_expression_tree_helper(prefix_exp, start_pos)
incr = left.size
right = create_expression_tree_helper(prefix_exp, start_pos+incr)
node = LinkedBinaryTree.Node(elem, left, right)
return node
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1))
return tree
EDIT here is a version that does not require to modify the Node
class
def create_expression_tree(prefix_exp_str):
expr_lst = prefix_exp_str.split(" ")
op = {'+': None, '-': None, '*': None, '/': None}
def create_expression_tree_helper(prefix_exp, start_pos):
start_pos += 1
elem = prefix_exp[start_pos]
node = None
size = 1
if elem not in op:
node = LinkedBinaryTree.Node(int(elem))
else:
left, left_size = create_expression_tree_helper(prefix_exp, start_pos)
right, right_size = create_expression_tree_helper(prefix_exp, start_pos+left_size)
node = LinkedBinaryTree.Node(elem, left, right)
size += left_size + right_size
return node, size
tree = LinkedBinaryTree(create_expression_tree_helper(expr_lst, -1)[0])
return tree
edited Nov 26 '18 at 16:39
answered Nov 25 '18 at 10:22
SilmathoronSilmathoron
1,0211721
1,0211721
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53454035%2frecursively-creating-a-binary-tree-given-a-string-expression-in-prefix-notation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Hi Kevin Chang, it is quite difficult to know what is going wrong without access to your
LinkedBinaryTree
class... do you have a GitHub repo or something? Otherwise at least give us the exact output from your terminal, and try to explain what the Nodes you add to your Tree are supposed to look like.– Silmathoron
Nov 24 '18 at 10:11
I uploaded my LinkedBinaryTree class as you've requested. Also, there is now a photo attached that shows the binary tree that should be created. Traversing this tree in prefix order should yield the values I mentioned before.
– Kevin Chang
Nov 24 '18 at 20:37
If possible, is there something that can be done with the implementation of the tree creator so that we do not have to modify the node class?
– Kevin Chang
Nov 26 '18 at 15:59
possible, but it would be less readable... is this really necessary?
– Silmathoron
Nov 26 '18 at 16:00
Yes, it was originally suggested to me to return a tuple in the recursive helper function to account for the increments, although I am confused as to how to implement that. I am not supposed to further modify the LinkedBinaryTree class and the node class.
– Kevin Chang
Nov 26 '18 at 16:30