The expression tree is a tree used to represent the various expressions. The tree data structure is used to represent the expressional statements. In this tree, the internal node always denotes the operators.
Expression trees play a very important role in representing the language-level code in the form of the data, which is mainly stored in the tree-like structure. It is also used in the memory representation of the lambda expression. Using the tree data structure, we can express the lambda expression more transparently and explicitly. It is first created to convert the code segment onto the data segment so that the expression can easily be evaluated.
The expression tree is a binary tree in which each external or leaf node corresponds to the operand and each internal or parent node corresponds to the operators so for example expression tree for 7 + ((1+8)*3) would be:
Let S be the expression tree
If S is not null, then
If S.value is an operand, then
Return S.value
x = solve(S.left)
y = solve(S.right)
Return calculate(x, y, S.value)
Here in the above example, the expression tree used context-free grammar.
We have some productions associated with some production rules in this grammar, mainly known as semantic rules. We can define the result-producing from the corresponding production rules using these semantic rules. Here we have used the value parameter, which will calculate the result and return it to the grammar's start symbol. S.left will calculate the left child of the node, and similarly, the right child of the node can be calculated using the S.right parameter.
To implement the expression tree and write its program, we will be required to use a stack data structure.
As we know that the stack is based on the last in first out LIFO principle, the data element pushed recently into the stack has been popped out whenever required. For its implementation, the main two operations of the stack, push and pop, are used. Using the push operation, we will push the data element into the stack, and by using the pop operation, we will remove the data element from the stack.
Main functions of the stack in the expression tree implementation
First of all, we will do scanning of the given expression into left to the right manner, then one by one check the identified character,
// C program for expression tree implementation
#include <stdio.h>
#include <stdlib.h>
/* The below structure node is defined as a node of a binary tree consists
of left child and the right child, along with the pointer next which points to the next node */
struct node
{
char info ;
struct node* l ;
struct node* r ;
struct node* nxt ;
};
struct node *head=NULL;
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
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 ;
else
{
/* first recur on left child */
Inorder ( node->l ) ;
/* then print the data of node */
printf ( "%c " , node->info ) ;
/* now recur on right child */
Inorder ( node->r ) ;
}
}
void push ( struct node* x )
{
if ( head == NULL )
head = x ;
else
{
( x )->nxt = head ;
head = x ;
}
// struct node* temp ;
// while ( temp != NULL )
// {
// printf ( " %c " , temp->info ) ;
// temp = temp->nxt ;
// }
}
struct node* pop()
{
// Poping out the top most [pointed with head] element
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 read character is operator then popping two
// other elements from stack and making a binary
// tree
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 ;
/* The below class node is defined as a node of a binary tree consists
of left child and the right child, along with the pointer next which points to the next node */
class node
{
public:
char info ;
node* l ;
node* r ;
node* nxt = NULL ;
node ( char c )
{
this->info = c ;
l = NULL ;
r = NULL ;
}
node()
{
l = NULL ;
r = NULL ;
}
friend class Stack ;
friend class tree ;
} ;
class Stack
{
node* head = NULL ;
public:
void push ( node* ) ;
node* pop() ;
friend class tree ;
} ;
class tree
{
public:
void inorder ( node* x )
{
// cout<<"Tree in InOrder Traversal is: "<<endl;
if ( x == NULL )
return ;
else
{
inorder ( x->l ) ;
cout << x->info << " " ;
inorder ( x->r ) ;
}
}
} ;
void Stack::push( node* x )
{
if ( head == NULL )
{
head = x ;
}
// We are inserting here nodes at the top of the stack [following LIFO principle]
else
{
x->nxt = head ;
head = x ;
}
}
node* Stack::pop()
{
// Poping out the top most [ pointed with head ] element
node* p = head ;
head = head->nxt ;
return p ;
}
int main()
{
string str = "XYZ*+W/" ;
// If you wish take input from user:
//cout << "Insert Postorder Expression: " << endl;
//cin >> s;
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.* ;
/* The below class node is defined as a node of a binary tree consists
of left child and the right child, along with the pointer next which points to the next node */
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 )
{
if ( ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' )
{
return true ;
}
return false ;
}
public static Node Tree ( String postfix )
{
Stack<Node> st = new Stack<Node>();
Node t1,t2,temp ;
for ( int i = 0 ; i < postfix.length(); i++ )
{
if ( !isOperator( postfix.charAt(i) ) )
{
temp = new Node( postfix.charAt(i) ) ;
st.push( temp ) ;
}
else
{
temp = new Node ( postfix.charAt(i) ) ;
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
119 docs|30 tests
|
|
Explore Courses for Computer Science Engineering (CSE) exam
|