# We need the Stack class. class Stack: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def peek(self): return self.items[len(self.items)-1] def size(self): return len(self.items) # And the Binary Tree class. class BinaryTree: def __init__(self, root_value, left=None, right=None): self.data = root_value self.left = left self.right = right def insert_left(self, value): self.left = BinaryTree(value, left=self.left) def insert_right(self, value): self.right = BinaryTree(value, right=self.right) def get_left_child(self): return self.left def get_right_child(self): return self.right def set_value(self, new_value): self.data = new_value def get_value(self): return self.data # A helper function to recursively build the str representation. def create_string(self, indent): string = str(self.data) if self.left: string += '\n' + indent + self.left.create_string(indent + ' ') if self.right: string += '\n' + indent + self.right.create_string(indent + ' ') return string def __str__(self): return self.create_string(' ') def is_number(token): """Check if the token is a number.""" try: float(token) except: return False else: return True # So now we can make an expression tree. def build_expression_tree(parenthesized_expression): """Builds an expression parse tree. parenthesized_expression -- a fully parenthesized expression """ token_list = parenthesized_expression.split() parent_stack = Stack() expression_tree = BinaryTree('') parent_stack.push(expression_tree) current_tree = expression_tree for token in token_list: if token == '(': current_tree.insert_left('') parent_stack.push(current_tree) current_tree = current_tree.get_left_child() elif token in ['+', '-', '*', '/']: current_tree.set_value(token) current_tree.insert_right('') parent_stack.push(current_tree) current_tree = current_tree.get_right_child() elif is_number(token): current_tree.set_value(float(token)) current_tree = parent_stack.pop() elif token == ')': current_tree = parent_stack.pop() else: raise ValueError return expression_tree import operator def evaluate(expression_tree): """Return the result of evaluating the expression.""" token = expression_tree.get_value() operations = {'+':operator.add, '-':operator.sub, '*':operator.mul, '/':operator.truediv} left = expression_tree.get_left_child() right = expression_tree.get_right_child() if left and right: return operations[token](evaluate(left), evaluate(right)) else: return token # N.B. the expression must have spaces between the tokens (this simplifies things) expression_tree = build_expression_tree("( ( 10 + 5 ) * 3 )") print(expression_tree) print('result =', evaluate(expression_tree)) expression_tree = build_expression_tree("( ( 9 - ( ( 2 * ( 10 + 5 ) ) * 3.5 ) ) / 3 )") print(expression_tree) print('result =', evaluate(expression_tree)) def print_preorder(tree): """Print the preorder traversal of the tree.""" if tree: print(tree.get_value(), end=' ') print_preorder(tree.get_left_child()) print_preorder(tree.get_right_child()) def print_postorder(tree): """Print the postorder traversal of the tree.""" if tree: print_postorder(tree.get_left_child()) print_postorder(tree.get_right_child()) print(tree.get_value(), end=' ') def print_inorder(tree): """Print the inorder traversal of the tree.""" if tree: print_inorder(tree.get_left_child()) print(tree.get_value(), end=' ') print_inorder(tree.get_right_child()) print_preorder(expression_tree) # prefix notation print() print_postorder(expression_tree) # postfix notation print() print_inorder(expression_tree) # infix notation