Skip to content
Related Articles

Related Articles

Program to convert Infix notation to Expression Tree
  • Difficulty Level : Medium
  • Last Updated : 22 Dec, 2020

Given a string representing infix notation. The task is to convert it to an expression tree.
Expression Tree is a binary tree where the operands are represented by leaf nodes and operators are represented by intermediate nodes. No node can have a single child.

Construction of Expression tree

The algorithm follows a combination of shunting yard along with postfix-to-expression tree conversion.

Consider the below line:

((s[i]!='^' && p[stC.top()]>=p[s[i]]) || 
(s[i]=='^' && p[stC.top()]>p[s[i]])))

You might remember that unlike ‘+’, ‘-‘, ‘*’ and ‘/’; ‘^’ is right associative. 
In simpler terms, a^b^c is a^(b^c) not (a^b)^c. So it must be evaluated from the right.



Now lets take a look at how does the algorithm work,(Take a quick glance at the code to get a better idea of the variables used) 

Let us have an expression s = ((a+b)*c-e*f)
currently both the stacks are empty- 
(we'll use C to denote the char stack and N for node stack)
    s[0] = '('            ((a+b)*c-e*f)
                          ^
        C|(|, N| |
    
    s[1] = '('           ((a+b)*c-e*f)
                          ^
         |(|  
        C|(|, N| |
                         
    s[2] = 'a'            ((a+b)*c-e*f)
                            ^
         |(|  
        C|(|, N|a|
                         
    s[3] = '+'            ((a+b)*c-e*f)
                             ^
         |+|
         |(|  
        C|(|, N|a|
        
    s[4] = 'b'             ((a+b)*c-e*f)
                               ^
         |+|
         |(|   |b|
        C|(|, N|a|
         
    s[5] = ')'             ((a+b)*c-e*f)
                                ^
         |+|            t = '+'         +
         |(|   |b|  ->  t1= 'b'        / \    ->  
        C|(|, N|a|      t2= 'a'       a   b      C|(|, N|+|
        
    s[6] = '*'              ((a+b)*c-e*f)
                                  ^
         |*|  
        C|(|, N|+|
    
    s[7] = 'c'              ((a+b)*c-e*f)
                                   ^
         |*|   |c|
        C|(|, N|+|
        
    s[8] = '-'   ((a+b)*c-e*f)              now (C.top(*)>s[8](-))
                         ^    t = '*'        *
         |*|   |c|            t1 = c        / \  ->    |-|
        C|(|, N|+|            t2 = +       +   c      C|(|, N|*|
                                          / \
                                         a   b
    s[9] = 'e'            ((a+b)*c-e*f)
                                   ^
         |-|   |e|
        C|(|, N|*|
        
    s[10] = '*'            ((a+b)*c-e*f)      now (C.top(-)>s[10](*))
                                     ^
         |*|                          
         |-|   |e| 
        C|(|, N|*|
    
    s[11] = 'f'             ((a+b)*c-e*f)
                                       ^
         |*|   |f|
         |-|   |e|
        C|(|, N|*|
    
    s[12] = ')'             ((a+b)*c-e*f)
       1>                               ^
         |*|   |f|         t = '*'          *        
         |-|   |e|  ->     t1= 'f'  ->     / \  ->   |-|   |*|
        C|(|, N|*|         t2= 'e'        e   f     C|(|, N|*|
        
       2>                               
                           t = '-'           -        
         |-|   |*|  ->     t1= '*'  ->     /   \  ->   
        C|(|, N|*|         t2= '*'        *     *     C| |, N|-|
                                         / \   / \
                                        +   c  e  f
                                       / \
                                      a   b 
      now make (-) the root of the tree

Below is the implementation of the above approach:

CPP

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Tree Structure
typedef struct node
{
    char data;
    struct node *left, *right;
} * nptr;
 
// Function to create new node
nptr newNode(char c)
{
    nptr n = new node;
    n->data = c;
    n->left = n->right = nullptr;
    return n;
}
 
// Function to build Expression Tree
nptr build(string& s)
{
 
    // Stack to hold nodes
    stack<nptr> stN;
 
    // Stack to hold chars
    stack<char> stC;
    nptr t, t1, t2;
 
    // Prioritising the operators
    int p[123] = { 0 };
    p['+'] = p['-'] = 1, p['/'] = p['*'] = 2, p['^'] = 3,
    p[')'] = 0;
 
    for (int i = 0; i < s.length(); i++)
    {
        if (s[i] == '(') {
 
            // Push '(' in char stack
            stC.push(s[i]);
        }
 
        // Push the operands in node stack
        else if (isalpha(s[i]))
        {
            t = newNode(s[i]);
            stN.push(t);
        }
        else if (p[s[i]] > 0)
        {
            // If an operator with lower or
            // same associativity appears
            while (
                !stC.empty() && stC.top() != '('
                && ((s[i] != '^' && p[stC.top()] >= p[s[i]])
                    || (s[i] == '^'
                        && p[stC.top()] > p[s[i]])))
            {
 
                // Get and remove the top element
                // from the character stack
                t = newNode(stC.top());
                stC.pop();
 
                // Get and remove the top element
                // from the node stack
                t1 = stN.top();
                stN.pop();
 
                // Get and remove the currently top
                // element from the node stack
                t2 = stN.top();
                stN.pop();
 
                // Update the tree
                t->left = t2;
                t->right = t1;
 
                // Push the node to the node stack
                stN.push(t);
            }
 
            // Push s[i] to char stack
            stC.push(s[i]);
        }
        else if (s[i] == ')') {
            while (!stC.empty() && stC.top() != '(')
            {
                t = newNode(stC.top());
                stC.pop();
                t1 = stN.top();
                stN.pop();
                t2 = stN.top();
                stN.pop();
                t->left = t2;
                t->right = t1;
                stN.push(t);
            }
            stC.pop();
        }
    }
    t = stN.top();
    return t;
}
 
// Function to print the post order
// traversal of the tree
void postorder(nptr root)
{
    if (root)
    {
        postorder(root->left);
        postorder(root->right);
        cout << root->data;
    }
}
 
// Driver code
int main()
{
    string s = "(a^b^(c/d/e-f)^(x*y-m*n))";
    s = "(" + s;
    s += ")";
    nptr root = build(s);
   
    // Function call
    postorder(root);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
// Tree Structure
static class nptr
{
    char data;
    nptr left, right;
} ;
 
// Function to create new node
static nptr newNode(char c)
{
    nptr n = new nptr();
    n.data = c;
    n.left = n.right = null;
    return n;
}
 
// Function to build Expression Tree
static nptr build(String s)
{
 
    // Stack to hold nodes
    Stack<nptr> stN = new Stack<>();
 
    // Stack to hold chars
    Stack<Character> stC = new Stack<>();
    nptr t, t1, t2;
 
    // Prioritising the operators
    int []p = new int[123];
    p['+'] = p['-'] = 1;
    p['/'] = p['*'] = 2;
    p['^'] = 3;
    p[')'] = 0;
 
    for (int i = 0; i < s.length(); i++)
    {
        if (s.charAt(i) == '(') {
 
            // Push '(' in char stack
            stC.add(s.charAt(i));
        }
 
        // Push the operands in node stack
        else if (Character.isAlphabetic(s.charAt(i)))
        {
            t = newNode(s.charAt(i));
            stN.add(t);
        }
        else if (p[s.charAt(i)] > 0)
        {
           
            // If an operator with lower or
            // same associativity appears
            while (
                !stC.isEmpty() && stC.peek() != '('
                && ((s.charAt(i) != '^' && p[stC.peek()] >= p[s.charAt(i)])
                    || (s.charAt(i) == '^'
                        && p[stC.peek()] > p[s.charAt(i)])))
            {
 
                // Get and remove the top element
                // from the character stack
                t = newNode(stC.peek());
                stC.pop();
 
                // Get and remove the top element
                // from the node stack
                t1 = stN.peek();
                stN.pop();
 
                // Get and remove the currently top
                // element from the node stack
                t2 = stN.peek();
                stN.pop();
 
                // Update the tree
                t.left = t2;
                t.right = t1;
 
                // Push the node to the node stack
                stN.add(t);
            }
 
            // Push s[i] to char stack
            stC.push(s.charAt(i));
        }
        else if (s.charAt(i) == ')') {
            while (!stC.isEmpty() && stC.peek() != '(')
            {
                t = newNode(stC.peek());
                stC.pop();
                t1 = stN.peek();
                stN.pop();
                t2 = stN.peek();
                stN.pop();
                t.left = t2;
                t.right = t1;
                stN.add(t);
            }
            stC.pop();
        }
    }
    t = stN.peek();
    return t;
}
 
// Function to print the post order
// traversal of the tree
static void postorder(nptr root)
{
    if (root != null)
    {
        postorder(root.left);
        postorder(root.right);
        System.out.print(root.data);
    }
}
 
// Driver code
public static void main(String[] args)
{
    String s = "(a^b^(c/d/e-f)^(x*y-m*n))";
    s = "(" + s;
    s += ")";
    nptr root = build(s);
   
    // Function call
    postorder(root);
}
}
 
// This code is contributed by aashish1995

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
 
// Tree Structure
public  class nptr
{
   public char data;
   public nptr left, right;
} ;
 
// Function to create new node
static nptr newNode(char c)
{
    nptr n = new nptr();
    n.data = c;
    n.left = n.right = null;
    return n;
}
 
// Function to build Expression Tree
static nptr build(String s)
{
 
    // Stack to hold nodes
    Stack<nptr> stN = new Stack<nptr>();
 
    // Stack to hold chars
    Stack<char> stC = new Stack<char>();
    nptr t, t1, t2;
 
    // Prioritising the operators
    int []p = new int[123];
    p['+'] = p['-'] = 1;
    p['/'] = p['*'] = 2;
    p['^'] = 3;
    p[')'] = 0;
 
    for (int i = 0; i < s.Length; i++)
    {
        if (s[i] == '(')
        {
 
            // Push '(' in char stack
            stC.Push(s[i]);
        }
 
        // Push the operands in node stack
        else if (char.IsLetter(s[i]))
        {
            t = newNode(s[i]);
            stN.Push(t);
        }
        else if (p[s[i]] > 0)
        {
           
            // If an operator with lower or
            // same associativity appears
            while (stC.Count != 0 && stC.Peek() != '('
                && ((s[i] != '^' && p[stC.Peek()] >= p[s[i]])
                    || (s[i] == '^'&& p[stC.Peek()] > p[s[i]])))
            {
 
                // Get and remove the top element
                // from the character stack
                t = newNode(stC.Peek());
                stC.Pop();
 
                // Get and remove the top element
                // from the node stack
                t1 = stN.Peek();
                stN.Pop();
 
                // Get and remove the currently top
                // element from the node stack
                t2 = stN.Peek();
                stN.Pop();
 
                // Update the tree
                t.left = t2;
                t.right = t1;
 
                // Push the node to the node stack
                stN.Push(t);
            }
 
            // Push s[i] to char stack
            stC.Push(s[i]);
        }
        else if (s[i] == ')')
        {
            while (stC.Count != 0 && stC.Peek() != '(')
            {
                t = newNode(stC.Peek());
                stC.Pop();
                t1 = stN.Peek();
                stN.Pop();
                t2 = stN.Peek();
                stN.Pop();
                t.left = t2;
                t.right = t1;
                stN.Push(t);
            }
            stC.Pop();
        }
    }
    t = stN.Peek();
    return t;
}
 
// Function to print the post order
// traversal of the tree
static void postorder(nptr root)
{
    if (root != null)
    {
        postorder(root.left);
        postorder(root.right);
        Console.Write(root.data);
    }
}
 
// Driver code
public static void Main(String[] args)
{
    String s = "(a^b^(c/d/e-f)^(x*y-m*n))";
    s = "(" + s;
    s += ")";
    nptr root = build(s);
   
    // Function call
    postorder(root);
}
}
 
// This code is contributed by aashish1995

chevron_right


 
 

Output

abcd/e/f-xy*mn*-^^^

The time Complexity is O(n) as each character is accessed only once. 
The space Complexity is O(n) as (char_stack + node_stack) <= n
  

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :