0% found this document useful (0 votes)
57 views30 pages

Binary Tree Applications

This document discusses binary trees and their applications in parsing expressions. It describes how expression trees can represent mathematical expressions and be used to evaluate them. The key steps of parsing an expression and building an expression tree are outlined, including maintaining a parent stack and implementing parsing rules with nodes and subtrees. Evaluation of an already built expression tree is also described through recursively applying operators on subtree results.

Uploaded by

Ayisha Afrin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
57 views30 pages

Binary Tree Applications

This document discusses binary trees and their applications in parsing expressions. It describes how expression trees can represent mathematical expressions and be used to evaluate them. The key steps of parsing an expression and building an expression tree are outlined, including maintaining a parent stack and implementing parsing rules with nodes and subtrees. Evaluation of an already built expression tree is also described through recursively applying operators on subtree results.

Uploaded by

Ayisha Afrin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 30

Binary Tree

Applications
Chapter 6.6

1
Parse Trees
• What is parsing?

• Originally from language study

• The breaking up of sentences into component


parts e.g. noun phrase

• In computing compilers and interpreters parse


programming languages.

• One aspect is parsing expressions.


107 - Trees 2
Expression Trees
• The leaves are values and the
other nodes are operators.

• We can use them to represent


and evaluate the expression.

• We work up from the bottom


evaluating subtrees.

• Compilers can use this to


generate efficient code - e.g.
how many registers are needed
to calculate this expression.

107 - Trees 3
Tokens
• Parsing starts with recognising tokens.

• A token is a symbol made up of one or more


characters (commonly separated by white space).

• e.g. a variable name or a number or an operator


“+”.

• For an expression tree the tokens are numbers,


operators and parentheses.

107 - Trees 4
Parsing Rules

• As we identify tokens we can apply rules to what we


should do.

• If the expression is fully parenthesised

• a left parenthesis “(“ starts a subtree

• a right parenthesis “)” finishes a subtree

107 - Trees 5
4 Rules
1.If the current token is a ‘(’, add a new node as the left child
of the current node, and descend to the left child.

2.If the current token is in the list [‘+’,’−’,’*’,‘/’], set the root
value of the current node to the operator represented by the
current token. Add a new node as the right child of the
current node and descend to the right child.

3.If the current token is a number, set the root value of the
current node to the number and return to the parent.

4.If the current token is a ‘)’, go to the parent of the current


node.
107 - Trees 6
(3 + (4 * 5))
Current node

107 - Trees 7
(3 + (4 * 5))

Current node

107 - Trees 8
(3 + (4 * 5))
Current node

107 - Trees 9
(3 + (4 * 5))
+

3 Current node

107 - Trees 10
(3 + (4 * 5))
+

Current node

107 - Trees 11
(3 + (4 * 5))
+

3 Current node

107 - Trees 12
(3 + (4 * 5))
+

3 *

107 - Trees 13
(3 + (4 * 5))
+

3 * Current node

4 5

107 - Trees 14
(3 + (4 * 5))
Current node +

3 *

4 5

107 - Trees 15
(3 + (4 * 5))
+

3 *

4 5

107 - Trees 16
Your turn

• Generate the expression tree for

((2 * ((3 - 4) + 6)) + 2)

107 - Trees 17
Keeping Track of the Parent
• We need to be able to move back up the tree.

• So we need to keep track of the parent of the current working node.

• We could do this with links from each child node back to its parent.

• Or we could store the tree in a list and use the 2 x n trick (if the tree
is not complete - most won’t be) then there will be lots of empty
space in this list.

• Or we could push the parent node onto a stack as we move down


the tree and pop parent nodes off the stack when we move back up.

107 - Trees 18
Build the tree code
set up

def build_expression_tree(parenthesized_expression):
"""Builds an expression parse tree.

parenthesized_expression -- a fully parenthesized expression


with spaces between tokens
"""
token_list = parenthesized_expression.split()
parent_stack = Stack()
expression_tree = BinaryTree('')
parent_stack.push(expression_tree)
current_tree = expression_tree

107 - Trees 19
Implementing the rules
1.If the current token is a ‘(’, add a new node as the
left child of the current node, and descend to the left
child.

for token in token_list:


if token == '(':
current_tree.insert_left('')
parent_stack.push(current_tree)
current_tree = current_tree.get_left_child()

107 - Trees 20
Implementing the rules
2.If the current token is in the list [‘+’,‘−’,‘*’,‘/’], set the
root value of the current node to the operator
represented by the current token. Add a new node
as the right child of the current node and descend to
the right 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()

107 - Trees 21
Implementing the rules
3.If the current token is a number, set the root value
of the current node to the number and return to the
parent.
elif is_number(token):
current_tree.set_value(float(token))
current_tree = parent_stack.pop()

def is_number(token):
"""Check if the token is a number."""
try:
float(token)
except:
return False
else:
return True

107 - Trees 22
Implementing the rules
4.If the current token is a ‘)’, go to the parent of the
current node.

elif token == ')':


current_tree = parent_stack.pop()
else:
raise ValueError

107 - Trees 23
Evaluating the expression

• Once we have generated the expression tree we


can easily evaluate the expression.

• In a compiler the expression would contain variables


which we wouldn’t know the value of until the
program ran, so the evaluation would be done at run
time.

107 - Trees 24
How would you evaluate?
+

3 * evaluate this subtree

4 5

107 - Trees 25
Algorithm
• To evaluate the subtree under a node

• if the node has children

• the node holds an operator

• return the result of applying the operator on the left


and right subtrees

• else the node held a number

• return the number


107 - Trees 26
Evaluation Code
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

107 - Trees 27
What is that operator stuff?
• The operator module provides functions to add,
subtract etc.

• We use a dictionary “operations” to connect the


tokens “+”, “-”, “*” and “/” with the corresponding
function.

• The line
operations[token](evaluate(left), evaluate(right))

evokes the function on its parameters.


107 - Trees 28
Tree Traversals
Text book Section 6.7

• With a binary tree we can recursively travel through all of the nodes (or traverse)
in three standard ways.

• We can deal with the node first then deal with the left subtree, then the right
subtree.

• This is a preorder traversal.

• We can deal with the left subtree, then with the node, then with the right subtree.

• This is an inorder traversal (and as we will see this keeps things in order).

• We can deal with the left subtree, then the right subtree and lastly the node
itself.

• This is a postorder traversal (we used this to evaluate expression trees).

107 - Trees 29
Code for printing tree
traversals
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())

107 - Trees 30

You might also like