Expression Trees
From charlesreid1
Contents
What Are Expression Trees
Expression trees are trees that represent expressions - pretty general definition.
More specifically and narrowly, we can think of expression trees as BINARY trees (see Binary Trees) representing arithmetical or syntax expressions. A few examples of syntax that can be assembled into expression trees:
- Postfix (reverse polish) notation
- Infix (normal human-readable operator) notation
- Nested parentheses (e.g., LISP)
Challenge Question
Programming question: Write a program that can parse a complex parentheses-based infix expression like,
"(a+b)/(c+(d*e))"
and turn it into its equivalent expression tree.
Converting Expressions to Trees
Strategy to processing expressions is to create your nested definition of an expression (or, a tree node) and simply go with it.
Keep the interface simple, use simple data structures like stacks, only implement the functionality you need.
Turn it into a tree when you're finished.
Postfix Expressions
Postfix expressions are a bit easier to turn into expression trees. Here's the basic idea:
For simple expressions like 3 5 +
while input queue has tokens: read a token if number, create single-node expression and push onto stack if operator, create three-node expression with operator at parent, left = pop from stack, right = pop from stack
Not handling more complicated syntax like 4 5 8 2 + * -
Infix Expressions
Complication here is not with multiple operators and operands, complication here is with parentheses
String/substring based method would iterate through the expression starting with innermost parentheses,
but this quickly gets complicated - multiple front/back pointers, non-sequential gaps, longer strings would be even worse
Strategy here is to process things as you see them, but be able to push things onto stack when only half-finished, for example 4 + (3 + (5 + (7 + 9)))
The algorithm looks like this:
while there are still tokens left in input queue: read a token if number, create single-node expression if prior item in stack is unbalanced operator, and prior char was not ( add to operator.right and push finished expression onto stack if operator create three-node expression with operator as parent operator.left = pop from stack push entire expression onto stack if close parentheses, if top of stack is unfinished operator, throw exception otherwise do nothing if open parentheses start single-node expression
When open parentheses, take whatever you were currently working on and push it on the stack
Shunting Yard Algorithm
Algorithm by Dijsktra, helps convert infix notation like 3+5 into postfiix notation like 3 5 +
Called the shunting yard because algorithm has structure of three data structures that work in tandem like a railroad shunting yard.
Input queue, processed one token at a time.
Operator stack, holds the operators that will be attached to the end of the expression
Output queue assembles the final expression
Flags
Trees Part of Computer Science Notes
Series on Data Structures Abstract data type: Trees/ADT Concrete implementations: Trees/LinkedTree · Trees/ArrayTree · SimpleTree
Tree Traversal Preorder traversal: Trees/Preorder Postorder traversal: Trees/Postorder In-Order traversal: Binary Trees/Inorder Breadth-First Search: BFS Breadth-First Traversal: BFT Depth-First Search: DFS Depth-First Traversal: DFT OOP Principles for Traversal: Tree Traversal/OOP · Tree Traversal/Traversal Method Template Tree operations: Trees/Operations Performance · Trees/Removal
Tree Applications Finding Minimum in Log N Time: Tree/LogN Min Search
Abstract data type: Binary Trees/ADT Concrete implementations: Binary Trees/LinkedBinTree · Binary Trees/ArrayBinTree Binary Trees/Cheat Sheet · Binary Trees/OOP · Binary Trees/Implementation Notes
|