expression trees Oct. 27, 2017 1 Binary tree: each node has at - - PowerPoint PPT Presentation

expression trees
SMART_READER_LITE
LIVE PREVIEW

expression trees Oct. 27, 2017 1 Binary tree: each node has at - - PowerPoint PPT Presentation

COMP 250 Lecture 21 binary trees, expression trees Oct. 27, 2017 1 Binary tree: each node has at most two children. 2 Maximum number of nodes in a binary tree? Height (e.g. 3) 3 Maximum number of nodes in a binary tree? Height


slide-1
SLIDE 1

1

COMP 250

Lecture 21

binary trees, expression trees

  • Oct. 27, 2017
slide-2
SLIDE 2

Binary tree:

each node has at most two children.

2

slide-3
SLIDE 3

Maximum number of nodes in a binary tree?

3

Height ℎ (e.g. 3)

slide-4
SLIDE 4

Maximum number of nodes in a binary tree?

4

Height ℎ (e.g. 3)

𝑜 = 1 + 2 + 4 + 8 + 2ℎ = 2ℎ+1 − 1

slide-5
SLIDE 5

Minimum number of nodes in a binary tree?

5

𝑜 = ℎ + 1

Height ℎ (e.g. 3)

slide-6
SLIDE 6

6

class BTree<T>{ BTNode<T> root; : class BTNode<T>{ T e; BTNode<T> leftchild; BTNode<T> rightchild; : } }

slide-7
SLIDE 7

Binary Tree Traversal (depth first)

7

depthFirst(root){ if (root is not empty){ visit root for each child of root depthFirst( child ) } }

Rooted tree Binary tree (last lecture)

slide-8
SLIDE 8

Binary Tree Traversal (depth first)

8

preorder(root){ if (root is not empty){ visit root for each child of root preorder( child ) } }

Rooted tree Binary tree (last lecture)

slide-9
SLIDE 9

Binary Tree Traversal (depth first)

9

preorderBT (root){ if (root is not empty){ visit root preorderBT( root.left ) preorderBT( root.right ) } } preorder(root){ if (root is not empty){ visit root for each child of root preorder( child ) } }

Rooted tree Binary tree (last lecture)

slide-10
SLIDE 10

10

preorderBT (root){ if (root is not empty){ visit root preorderBT( root.left ) preorderBT( root.right ) } } postorderBT (root){ }

slide-11
SLIDE 11

11

preorderBT (root){ if (root is not empty){ visit root preorderBT( root.left ) preorderBT( root.right ) } } postorderBT (root){ if (root is not empty){ postorderBT(root.left) postorderBT(root.right) visit root } }

slide-12
SLIDE 12

12

inorderBT (root){ if (root is not empty){ inorderBT(root.left) visit root inorderBT(root.right) } } preorderBT (root){ if (root is not empty){ visit root preorderBT( root.left ) preorderBT( root.right ) } } postorderBT (root){ if (root is not empty){ postorderBT(root.left) postorderBT(root.right) visit root } }

slide-13
SLIDE 13

13

inorderBT (root){ if (root is not empty){ inorderBT(root.left) visit root inorderBT(root.right) } } preorderBT (root){ if (root is not empty){ visit root preorderBT( root.left ) preorderBT( root.right ) } } postorderBT (root){ if (root is not empty){ postorderBT(root.left) postorderBT(root.right) visit root } }

slide-14
SLIDE 14

Example

14

a b c d e f g

Pre order: In order: Post order:

slide-15
SLIDE 15

Example

15

a b c d e f g

Pre order: a b d e c f g In order: Post order:

slide-16
SLIDE 16

Example

16

a b c d e f g

Pre order: a b d e c f g In order: d e b a f c g Post order:

slide-17
SLIDE 17

Example

17

a b c d e f g

Pre order: a b d e c f g In order: d e b a f c g Post order: e d b f g c a

slide-18
SLIDE 18

Expression Tree

18

+ 3 * 4 2

e.g. 3 + 4 * 2

3 + (4 * 2)

slide-19
SLIDE 19

Expression Tree

19

+ 3 * 4 2 * + 2 3 4

e.g. 3 + 4 * 2

(3 + 4) * 2 3 + (4 * 2)

slide-20
SLIDE 20

20

My Windows calculator says 3 + 4 * 2 = 14. Why? (3 + 4) * 2 = 14. Whereas…. if I google “3+4*2”, I get 11. 3 + (4*2) = 11.

slide-21
SLIDE 21

21

^ is exponentiation: e ^ f ^ g = e ^ (f ^ g) We don’t consider unary operators e.g. 3 + -4 = 3 + (-4) Operator precedence ordering makes brackets unnecessary. (a – (b / c)) + (d * (e ^ (f ^ g))) We can make expressions using binary operators +, -, *, /, ^ e.g. a – b / c + d * e ^ f ^ g

slide-22
SLIDE 22

Expression Tree

22

a – b / c + d * e ^ f ^ g ≡ (a – (b / c)) + (d ∗ (e ^ (f ^ g))) e f g / * a d + b c Internal nodes are operators. Leaves are operands.

slide-23
SLIDE 23

23

e f g / * a d + b c

An expression tree can be a way of thinking about the ordering of

  • perations used when evaluating an expression.

But to be concrete, let’s assume we have a binary tree data structure.

slide-24
SLIDE 24

24

preorder traversal gives e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-25
SLIDE 25

25

preorder traversal gives : + – a / b c * d ^ e ^ f g e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-26
SLIDE 26

26

preorder traversal gives : + – a / b c * d ^ e ^ f g inorder traversal gives : e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-27
SLIDE 27

27

preorder traversal gives : + – a / b c * d ^ e ^ f g inorder traversal gives : a – b / c + d * e ^ f ^ g e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-28
SLIDE 28

28

preorder traversal gives : + – a / b c * d ^ e ^ f g inorder traversal gives : a – b / c + d * e ^ f ^ g postorder traversal gives : e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-29
SLIDE 29

29

preorder traversal gives : + – a / b c * d ^ e ^ f g inorder traversal gives : a – b / c + d * e ^ f ^ g postorder traversal gives : a b c / - d e f g ^ ^ * + e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out?

slide-30
SLIDE 30

Prefix, infix, postfix expressions

30

prefix: * a b infix: a * b postfix: a b *

* a b

slide-31
SLIDE 31

Infix, prefix, postfix expressions

31

baseExp = variable | integer

  • p = + | - | * | / | ^

preExp = baseExp | op preExp preExp

slide-32
SLIDE 32

Infix, prefix, postfix expressions

32

baseExp = variable | integer

  • p = + | - | * | / | ^

preExp = baseExp | op preExp prefExp inExp = baseExp | inExp op inExp postExp = baseExp | postExp postExp

  • p

Use

  • nly
  • ne.
slide-33
SLIDE 33

33

preorder traversal gives prefix expression: + – a / b c * d ^ e ^ f g inorder traversal gives infix expression: a – b / c + d * e ^ f ^ g postorder traversal gives postfix expression: a b c / - d e f g ^ ^ * +

e f g

/

* a d + b c If we traverse an expression tree, and print out the node label, what is the expression printed out? (same question as four slides ago)

slide-34
SLIDE 34

34

Prefix expressions called “Polish Notation”

(after Polish logician Jan Lucasewicz 1920’s)

Postfix expressions are called “Reverse Polish notation” (RPN)

Some calculators (esp. Hewlett Packard) require users to input expressions using RPN.

slide-35
SLIDE 35

35

Prefix expressions called “Polish Notation”

(after Polish logician Jan Lucasewicz 1920’s)

Postfix expressions are called “Reverse Polish notation” (RPN)

Some calculators (esp. Hewlett Packard) require users to input expressions using RPN. Calculate 5 * 4 + 3 : 5 <enter> 4 <enter> * <enter> 3 <enter> + <enter> No “=“ symbol on keyboard.

slide-36
SLIDE 36

36

Suppose we are given an expression tree. How can we evaluate the expression ? e f g / * a d + b c

slide-37
SLIDE 37

37

We use a postorder traversal (recursive algorithm): evalExpTree(root){ if (root is a leaf) // root is a number return value else{ // the root is an operator firstOperand = evalExpTree( root.leftchild ) secondOperand = evalExpTree( root.rightchild ) return evaluate(firstOperand, root, secondOperand) } }

slide-38
SLIDE 38

38

What if we are not given an expression tree? Infix expressions are awkward to evaluate because of precedence ordering. Infix expressions with brackets are relatively easy to evaluate e.g. Assignment 2.

slide-39
SLIDE 39

39

Assignment 2 (ignore case of ++, --)

for each token in expression { if token is a number valueStack.push(token) else if token is “)” { // then you have a binary expression

  • perator = opStack.pop()
  • perand2 = valueStack.pop()
  • perand1 = valueStack.pop()

numStack.push( operand1 operator operand2) } } return valueStack.pop()

slide-40
SLIDE 40

40

Assignment 2 (ignore case of ++, --)

for each token in expression { if token is a number valueStack.push(token) else if token is “)” { // then you have a binary expression

  • perator = opStack.pop()
  • perand2 = valueStack.pop()
  • perand1 = valueStack.pop()

numStack.push( operand1 operator operand2) } } return valueStack.pop()

slide-41
SLIDE 41

41

Infix expressions with brackets are relatively easy to evaluate e.g. with two stacks as in Assignment 2. Postfix expressions without brackets are easy to evaluate. Use one stack, namely for values (not operators).

slide-42
SLIDE 42

42

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a stack

  • ver

time

e f g / * a d + b c

Example:

This expression tree is not given. It is shown here so that you can visualize the expression more easily.

slide-43
SLIDE 43

43

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c stack

  • ver

time

e f g / * a d + b c

Example:

This expression tree is not given. It is shown here so that you can visualize the expression more easily.

slide-44
SLIDE 44

44

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c a (b c / ) stack

  • ver

time

e f g / * a d + b c

We don’t push operator onto stack. Instead we pop value twice, evaluate, and push.

slide-45
SLIDE 45

45

Useon: a b c / - d e f g ^ ^ * +

a a b a b c a (b c / ) ( a ( b c / ) - ) stack

  • ver

time

e f g / * a d + b c

Now there is one value on the stack.

slide-46
SLIDE 46

46

tack to eval: a b c / - d e f g ^ ^ * +

a a b a b c a (b c / ) ( a ( b c / ) - ) : ( a ( b c / ) - ) d e f g stack

  • ver

time

e f g / * a d + b c

Now there are five values on the stack.

slide-47
SLIDE 47

47

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c a ( b c / ) ( a ( b c / ) - ) : ( a ( b c / ) - ) d e f g ( a ( b c / ) - ) d e (f g ^) stack

  • ver

time

e f g / * a d + b c

Now there are four values on the stack.

slide-48
SLIDE 48

48

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c a ( b c / ) ( a ( b c / ) - ) : ( a ( b c / ) - ) d e f g ( a ( b c / ) - ) d e (f g ^) ( a ( b c / ) - ) d ( e (f g ^) ^ ) stack

  • ver

time

e f g / * a d + b c

Three values on the stack.

slide-49
SLIDE 49

49

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c a ( b c / ) ( a ( b c / ) - ) : ( a ( b c / ) - ) d e f g ( a ( b c / ) - ) d e (f g ^) ( a ( b c / ) - ) d ( e (f g ^) ^ ) ( a ( b c / ) - ) (d ( e (f g ^) ^ ) * ) stack

  • ver

time

e f g / * a d + b c

Two values on the stack.

slide-50
SLIDE 50

50

Use a stack to evaluate postfix expression: a b c / - d e f g ^ ^ * +

a a b a b c a ( b c / ) ( a ( b c / ) - ) : ( a ( b c / ) - ) d e f g ( a ( b c / ) - ) d e (f g ^) ( a ( b c / ) - ) d ( e (f g ^) ^ ) ( a ( b c / ) - ) (d ( e (f g ^) ^ ) * ) ( ( a ( b c / ) - ) (d ( e (f g ^) ^ ) * ) + ) stack

  • ver

time

e f g / * a d + b c

One value on the stack.

slide-51
SLIDE 51

51

Algorithm: Use a stack to evaluate a postfix expression

Let expression be a list of elements. s = empty stack cur = first element of expression list while (cur != null){ if ( cur.element is a base expression ) s.push( cur.element ) else{ // cur.element is an operator

  • perand2 = s.pop()
  • perand1 = s.pop()
  • perator = cur.element

// for clarity only s.push( evaluate( operand1, operator, operand2 ) ) } cur = cur.next }

slide-52
SLIDE 52

52

Algorithm: Use a stack to evaluate a postfix expression

Let expression be a list of elements. s = empty stack cur = first element of expression list while (cur != null){ if ( cur.element is a base expression ) s.push( cur.element ) else{ // cur.element is an operator

  • perand2 = s.pop()
  • perand1 = s.pop()
  • perator = cur.element

// for clarity only s.push( evaluate( operand1, operator, operand2 ) ) } cur = cur.next }

slide-53
SLIDE 53

ASIDE

53

There are many variations of expression tree problems. e.g. Define an algorithm that computes a postfix expression directly from an infix expression with no

  • brackets. This is not so obvious if you have to respect

precedence ordering e.g. +, -, *, /, ^

http://wcipeg.com/wiki/Shunting_yard_algorithm