Recursively Creating a Binary Tree Given a String Expression in Prefix Notation in Python












1















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.










share|improve this question




















  • 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
















1















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.










share|improve this question




















  • 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














1












1








1








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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














  • 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








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












1 Answer
1






active

oldest

votes


















0














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 to Node


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





share|improve this answer

























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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 to Node


    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





    share|improve this answer






























      0














      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 to Node


      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





      share|improve this answer




























        0












        0








        0







        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 to Node


        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





        share|improve this answer















        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 to Node


        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






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 26 '18 at 16:39

























        answered Nov 25 '18 at 10:22









        SilmathoronSilmathoron

        1,0211721




        1,0211721






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Berounka

            Fiat S.p.A.

            Type 'String' is not a subtype of type 'int' of 'index'