Program to convert Infix notation to Expression Tree - GeeksforGeeks

27 Aug, 2021
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:
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; // Tree Structuretypedef struct node{    char data;    struct node *left, *right;} * nptr; // Function to create new nodenptr newNode(char c){    nptr n = new node;    n->data = c;    n->left = n->right = nullptr;    return n;} // Function to build Expression Treenptr 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 treevoid postorder(nptr root){    if (root)    {        postorder(root->left);        postorder(root->right);        cout << root->data;    }} // Driver codeint 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;}
// Java implementation of the approachimport java.util.*; class GFG{ // Tree Structurestatic class nptr{    char data;    nptr left, right;} ; // Function to create new nodestatic nptr newNode(char c){    nptr n = new nptr();    n.data = c;    n.left = n.right = null;    return n;} // Function to build Expression Treestatic 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 treestatic void postorder(nptr root){    if (root != null)    {        postorder(root.left);        postorder(root.right);        System.out.print(root.data);    }} // Driver codepublic 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
# Python3 implementation of the approach # Tree Structureclass nptr:       # Constructor to set the data of    # the newly created tree node    def __init__(self, c):        self.data = c        self.left = None        self.right = None # Function to create new nodedef newNode(c):    n = nptr(c)    return n # Function to build Expression Treedef build(s):       # Stack to hold nodes    stN = []     # Stack to hold chars    stC = []     # Prioritising the operators    p = [0]*(123)    p[ord('+')] = p[ord('-')] = 1    p[ord('/')] = p[ord('*')] = 2    p[ord('^')] = 3    p[ord(')')] = 0     for i in range(len(s)):        if (s[i] == '('):            # Push '(' in char stack            stC.append(s[i])         # Push the operands in node stack        elif (s[i].isalpha()):            t = newNode(s[i])            stN.append(t)        elif (p[ord(s[i])] > 0):                       # If an operator with lower or            # same associativity appears            while (len(stC) != 0 and stC[-1] != '(' and ((s[i] != '^' and p[ord(stC[-1])] >= p[ord(s[i])])                    or (s[i] == '^'and                    p[ord(stC[-1])] > p[ord(s[i])]))):                               # Get and remove the top element                # from the character stack                t = newNode(stC[-1])                stC.pop()                 # Get and remove the top element                # from the node stack                t1 = stN[-1]                stN.pop()                 # Get and remove the currently top                # element from the node stack                t2 = stN[-1]                stN.pop()                 # Update the tree                t.left = t2                t.right = t1                 # Push the node to the node stack                stN.append(t)             # Push s[i] to char stack            stC.append(s[i])                     elif (s[i] == ')'):            while (len(stC) != 0 and stC[-1] != '('):                t = newNode(stC[-1])                stC.pop()                t1 = stN[-1]                stN.pop()                t2 = stN[-1]                stN.pop()                t.left = t2                t.right = t1                stN.append(t)            stC.pop()    t = stN[-1]    return t # Function to print the post order# traversal of the treedef postorder(root):    if (root != None):        postorder(root.left)        postorder(root.right)        print(root.data, end = "") s = "(a^b^(c/d/e-f)^(x*y-m*n))"s = "(" + ss += ")"root = build(s) # Function callpostorder(root) # This code is contributed by divyeshrabadiya07.
// C# implementation of the approachusing System;using System.Collections.Generic;class GFG{ // Tree Structurepublic  class nptr{   public char data;   public nptr left, right;} ; // Function to create new nodestatic nptr newNode(char c){    nptr n = new nptr();    n.data = c;    n.left = n.right = null;    return n;} // Function to build Expression Treestatic 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 treestatic void postorder(nptr root){    if (root != null)    {        postorder(root.left);        postorder(root.right);        Console.Write(root.data);    }} // Driver codepublic 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
<script>     // JavaScript implementation of the approach         // Tree Structure    class nptr    {       constructor(c) {           this.left = null;           this.right = null;           this.data = c;        }    }     // Function to create new node    function newNode(c)    {        let n = new nptr(c);        return n;    }     // Function to build Expression Tree    function build(s)    {         // Stack to hold nodes        let stN = [];         // Stack to hold chars        let stC = [];        let t, t1, t2;         // Prioritising the operators        let p = new Array(123);        p['+'.charCodeAt()] = p['-'.charCodeAt()] = 1;        p['/'.charCodeAt()] = p['*'.charCodeAt()] = 2;        p['^'.charCodeAt()] = 3;        p[')'.charCodeAt()] = 0;         for (let 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 ((/[a-zA-Z]/).test(s[i]))            {                t = newNode(s[i]);                stN.push(t);            }            else if (p[s[i].charCodeAt()] > 0)            {                 // If an operator with lower or                // same associativity appears                while (stC.length != 0 && stC[stC.length - 1] != '('                    && ((s[i] != '^' &&                    p[stC[stC.length - 1].charCodeAt()] >=                    p[s[i].charCodeAt()])                        || (s[i] == '^'&&                        p[stC[stC.length - 1].charCodeAt()] >                        p[s[i].charCodeAt()])))                {                     // Get and remove the top element                    // from the character stack                    t = newNode(stC[stC.length - 1]);                    stC.pop();                     // Get and remove the top element                    // from the node stack                    t1 = stN[stN.length - 1];                    stN.pop();                     // Get and remove the currently top                    // element from the node stack                    t2 = stN[stN.length - 1];                    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.length != 0 &&                stC[stC.length - 1] != '(')                {                    t = newNode(stC[stC.length - 1]);                    stC.pop();                    t1 = stN[stN.length - 1];                    stN.pop();                    t2 = stN[stN.length - 1];                    stN.pop();                    t.left = t2;                    t.right = t1;                    stN.push(t);                }                stC.pop();            }        }        t = stN[stN.length - 1];        return t;    }     // Function to print the post order    // traversal of the tree    function postorder(root)    {        if (root != null)        {            postorder(root.left);            postorder(root.right);            document.write(root.data);        }    }         let s = "(a^b^(c/d/e-f)^(x*y-m*n))";    s = "(" + s;    s += ")";    let root = build(s);        // Function call    postorder(root);     </script>
  
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  
Julkar9
aashish1995
rameshtravel07
divyeshrabadiya07
Data Structures
Stack
Tree
Data Structures
Stack
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Start Learning DSA?
Introduction to Tree Data Structure
Program to implement Singly Linked List in C++ using class
Hash Functions and list/types of Hash functions
Insertion in a B+ tree
Stack Data Structure (Introduction and Program)
Stack Class in Java
Stack in Python
Check for Balanced Brackets in an expression (well-formedness) using Stack
Stack | Set 2 (Infix to Postfix)