Tree Applications Processing sentences (computer programs or natural languages) Searchable data structures Heaps (implement heap sort, priority queues)
A Parse (Expression) Tree Source language program Ok or not OK Parser A parse tree Evaluator The value of the expression Syntax error messages Semantic error messages
Trees for Binary Expressions An expression tree for a number is a node containing the number Otherwise, the tree is a node containing an operator and links to left and right subtrees The subtrees contain the operands of the expression
Example Expression Trees 23 23
Example Expression Trees 23 23 3 + 5 + 3 5 Root node Right subtree Left subtree
Example Expression Trees 23 23 3 + 5 + 3 5 Root node Right subtree Left subtree
Example Expression Trees 23 23 3 + 5 + 3 5 Root node Right subtree Left subtree (3 + 5) * 4 * + 3 5 4
Operator Precedence (3 + 5) * 4 * + 3 5 4 5 * 4 + 3 + * 3 Operators with higher precedence appear lower in the tree, unless overridden by parentheses.
Operator Precedence + 5 * 4-3 - 5 + 4-3 + 6-6 * 3 + 3 5 + 4-3 - + 3 When operators have equal precedence, the ones to the left appear lower in the tree.
Other Properties of Expr Trees Numbers are leaf nodes Operators are interior nodes All interior nodes have two children
Evaluating an Expression Tree Begin at the root node If the node contains a number, return it Otherwise, run the operator in the node with the results of evaluating its left and right subtrees, and return this value
Evaluate This One Contains an operator, so evaluate left and right subtrees
Evaluate This One Contains a number, so return 3
Evaluate This One Contains an operator, so evaluate left and right subtrees
Evaluate This One Contains a number, so return 5
Evaluate This One Contains a number, so return 4
Evaluate This One Return 5 * 4 = 20
Evaluate This One Return 3 + 20 = 23
Pseudocode for evaluate int evaluate(node) If node is a number Return the number Else Set leftoperand to evaluate(node.left) Set rightoperand to evaluate(node.right) Return computevalue(node, leftoperand, rightoperand)
Tree Traversals An expression tree supports three types of traversals preorder (visit node, then go left, then go right) inorder (go left, then visit node, then go right) postorder (go left, then go right, then visit node
Tree Traversals An expression tree supports three types of traversals preorder (visit node, then go left, then go right) inorder (go left, then visit node, then go right) postorder (go left, then go right, then visit node These traversals can generate the prefix, infix, and postfix notations of an expression
Pseudocode for prefix String prefix(node) If node is null return "" else Return node + prefix(node.left) + prefix(node.right)
Pseudocode for infix String infix(node) If node is null return "" else Return "(" + infix(node.left) + node + infix(node.right) + ")"
Pseudocode for postfix String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node not null, so go left String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node not null, so go left String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Now go right String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Return "3" 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Now go right 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node not null, so go left 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node not null, so go left 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Now go right 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Return "5" 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Now go right 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node not null, so go left 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Now go right 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Node is null, return " " 3 5 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Return "4" 3 String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Return "*" 3 * String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
Generate Postfix Return "+" 3 * + String postfix(node) If node is null return "" else Return postfix(node.left) + postfix(node.right) + node
The Class BTNode private class BTNode extends Object{ private Object value; // Value stored in this node private BTNode left; // Reference to left child private BTNode right; // Reference to right child private BTNode(Object value){ this.value = value; left = null; right = null; } } private BTNode(Object value, BTNode left, BTNode right){ this.value = value; this.left = left; this.right = right; }
The Class ExpressionTree public class ExpressionTree extends Object { private BTNode root; public ExpressionTree(Token token){ root = new BTNode (token); } public ExpressionTree(Token token, ExpressionTree lefttree, ExpressionTree righttree){ root = new BTNode (token, lefttree.root, righttree.root); } } // Other methods and the class BTNode go here
Generating Postfix public String postfix(){ return postfix (root); } private String postfix (BTNode node){ if (node == null) return ""; else return postfix (node.left) + postfix (node.right) + node.value.tostring(); }
Building an Expression Tree Each parsing method builds a tree that represents the portion of the expression for which it is responsible Each parsing method returns its tree to the caller
A Tree for Primaries private ExpressionTree primary(){ ExpressionTree tree; Token token = scanner.get(); switch (token.type){ case Token.INT: tree = new ExpressionTree(token); scanner.next(); break; case Token.L_PAR: scanner.next(); tree = expression(); accept (scanner.get(), Token.R_PAR, "')' expected"); scanner.next(); break; default: tree = null; fatalerror (token, "unexpected token"); } return tree; }
A Tree for Expressions private ExpressionTree expression(){ ExpressionTree tree = term(); Token token = scanner.get(); while (token.type == Token.PLUS token.type == Token.MINUS){ scanner.next(); tree = new ExpressionTree(token, tree, term()); token = scanner.get(); } return tree; }