Convert ternary expression to Binary Tree using Stack

Given a string str that contains a ternary expression which may be nested. The task is to convert the given ternary expression to a binary tree and return the root.

Examples:

Input: str = "a?b:c"
Output: a b c
  a
 / \
b   c
The preorder traversal of the above tree is a b c.

Input: str = "a?b?c:d:e"
Output: a b c d e
    a
   / \
  b   e
 / \
c   d

Approach: This is a stack-based approach to the given problem. Since the ternary operator has associativity from right-to-left, the string can be traversed from right to left. Take the letters one by one skipping the letters ‘?’ and ‘:’ as these letters are used to decide whether the current letter (alphabet [a to z]) will go into the stack or be used to pop the top 2 elements from the top of the stack to make them the children of the current letter which is then itself pushed into the stack. This forms the tree in a bottom-up manner and the last remaining element in the stack after the entire string is processed is the root of the tree.



Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Node structure
struct Node {
    char data;
    Node *left, *right;
};
  
// Function to create a new node
Node* createNewNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = NULL, node->right = NULL;
    return node;
}
  
// Function to print the preorder
// traversal of the tree
void preorder(Node* root)
{
    if (root == NULL)
        return;
    cout << root->data << " ";
    preorder(root->left);
    preorder(root->right);
}
  
// Function to convert the expression to a binary tree
Node* convertExpression(string str, int i)
{
    stack<Node*> s;
  
    // If the letter is the last letter of
    // the string or is of the type :letter: or ?letter:
    // we push the node pointer containing
    // the letter to the stack
    for (i = str.length() - 1; i >= 0;) {
        if ((i == str.length() - 1)
            || (i != 0 && ((str[i - 1] == ':'
                            && str[i + 1] == ':')
                           || (str[i - 1] == '?'
                               && str[i + 1] == ':')))) {
            s.push(createNewNode(str[i]));
        }
  
        // If we do not push the current letter node to stack,
        // it means the top 2 nodes in the stack currently are the
        // left and the right children of the current node
        // So pop these elements and assign them as the
        // children of the current letter node and then
        // push this node into the stack
        else {
            Node* lnode = s.top();
            s.pop();
            Node* rnode = s.top();
            s.pop();
            Node* node = createNewNode(str[i]);
            node->left = lnode;
            node->right = rnode;
            s.push(node);
        }
        i -= 2;
    }
  
    // Finally, there will be only 1 element
    // in the stack which will be the
    // root of the binary tree
    return s.top();
}
  
// Driver code
int main()
{
    string str = "a?b?c:d:e";
  
    // Convert expression
    Node* root = convertExpression(str, 0);
  
    // Print the preorder traversal
    preorder(root);
  
    return 0;
}

chevron_right


Output:

a b c d e

Time Complexity: O(n)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.