An expression tree is a binary tree that represents arithmetic or logical expressions. In an expression tree each internal node represents an operator and each leaf node represents an operand. The tree structure encodes the order of evaluation: operators near the leaves are applied before operators near the root (subject to explicit precedence and associativity encoded when the tree is built).
Consider the expression 7 + ((1 + 8) × 3). An expression tree for this expression has + as the root, 7 as the left child, and a subtree representing ((1 + 8) × 3) as the right child.

The usual recursive evaluation of an expression tree computes values by a post-order traversal: evaluate left subtree, evaluate right subtree, then apply the operator at the node.
function evaluate(node)
if node is null
return 0 // or error for empty tree
if node is a leaf
return numeric_value(node)
x = evaluate(node.left)
y = evaluate(node.right)
return apply_operator(node.operator, x, y)
For the example 7 + ((1 + 8) × 3) the recursive computation proceeds by computing (1 + 8) = 9, then 9 × 3 = 27, then 7 + 27 = 34.
Building an expression tree from a postfix expression is straightforward using a stack:
To build from prefix notation, scan from right to left and apply the same stack-based idea: push operands, and when an operator is encountered, pop two nodes to become its children and push the new operator node back.
Constructing an expression tree directly from infix requires handling precedence and associativity. A common method is to first convert infix to postfix (for example using the Shunting Yard algorithm) and then build the tree from the resulting postfix expression.
Given the postfix string "XYZ*+W/", the stack-based procedure produces a tree whose inorder traversal prints:
X + Y * Z / W
The following implementations demonstrate construction of an expression tree from a postfix expression and printing the inorder traversal. Each program uses the stack push/pop operations and a node structure/class that stores an operator/operand and left/right pointers.
// C program for expression tree implementation
#include <stdio.h>
#include <stdlib.h>
struct node {
char info;
struct node* l;
struct node* r;
struct node* nxt; // used to implement stack as linked list
};
struct node *head = NULL;
struct node* newnode(char data) {
struct node* node = (struct node*) malloc(sizeof(struct node));
node->info = data;
node->l = NULL;
node->r = NULL;
node->nxt = NULL;
return node;
}
void Inorder(struct node* node) {
if (node == NULL)
return;
Inorder(node->l);
printf("%c ", node->info);
Inorder(node->r);
}
void push(struct node* x) {
if (head == NULL)
head = x;
else {
x->nxt = head;
head = x;
}
}
struct node* pop() {
struct node* n = head;
head = head->nxt;
return n;
}
int main() {
char t[] = { 'X', 'Y', 'Z', '*', '+', 'W', '/' };
int n = sizeof(t) / sizeof(t[0]);
int i;
struct node *p, *q, *s;
for (i = 0; i < n;="" i++)="" {="" if="" (t[i]="=" '+'="" ||="" t[i]="=" '-'="" ||="" t[i]="=" '*'="" ||="" t[i]="=" '/'="" ||="" t[i]="=" '^')="" {="" s="newnode(t[i]);" p="pop();" q="pop();" s-="">l = q;
s->r = p;
push(s);
} else {
s = newnode(t[i]);
push(s);
}
}
printf("The Inorder Traversal of Expression Tree: ");
Inorder(s);
return 0;
}
The output of the above program is:
X + Y * Z / W
// C++ program for expression tree
#include <bits/stdc++.h>
using namespace std;
class node {
public:
char info;
node* l;
node* r;
node* nxt;
node(char c) {
info = c;
l = NULL;
r = NULL;
nxt = NULL;
}
};
class Stack {
node* head = NULL;
public:
void push(node* x) {
if (head == NULL)
head = x;
else {
x->nxt = head;
head = x;
}
}
node* pop() {
node* p = head;
head = head->nxt;
return p;
}
};
class tree {
public:
void inorder(node* x) {
if (x == NULL) return;
inorder(x->l);
cout < x-="">info < "="" ";="" inorder(x-="">r);
}
};
int main() {
string str = "XYZ*+W/";
Stack s;
tree t;
node *p, *q, *re;
int n = str.length();
for (int i = 0; i < n; i++) {
if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '^') {
re = new node(str[i]);
p = s.pop();
q = s.pop();
re->l = q;
re->r = p;
s.push(re);
} else {
re = new node(str[i]);
s.push(re);
}
}
cout << "The Inorder Traversal of Expression Tree: ";
t.inorder(re);
return 0;
}
The output of the above program is:
X + Y * Z / W
// Java program for expression tree
import java.util.*;
class Node {
char info;
Node l, r;
public Node(char data) {
this.info = data;
l = null;
r = null;
}
}
public class Main {
public static boolean isOperator(char ch) {
return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^');
}
public static Node Tree(String postfix) {
Stack<Node> st = new Stack<Node>();
Node t1, t2, temp;
for (int i = 0; i < postfix.length(); i++) {
char ch = postfix.charAt(i);
if (!isOperator(ch)) {
temp = new Node(ch);
st.push(temp);
} else {
temp = new Node(ch);
t1 = st.pop();
t2 = st.pop();
temp.l = t2;
temp.r = t1;
st.push(temp);
}
}
temp = st.pop();
return temp;
}
public static void inorder(Node parent) {
if (parent == null) return;
inorder(parent.l);
System.out.print(parent.info + " ");
inorder(parent.r);
}
public static void main(String[] args) {
String postfix = "XYZ*+W/";
Node r = Tree(postfix);
inorder(r);
}
}
The output of the above program is:
X + Y * Z / W
Expression trees are a compact and clear representation of expressions that make evaluation, notation conversion and programmatic transformations straightforward. They are a standard tool in compilers, interpreters and symbolic-manipulation systems. Understanding how to build an expression tree from postfix/prefix/infix forms and how to traverse and evaluate it is essential in data structures, compiler construction and related areas of computer science.
|
Explore Courses for Computer Science Engineering (CSE) exam
|
|
|
Get EduRev Notes directly in your Google search
|
|