{x}
blog image

Build Binary Expression Tree From Infix Expression

Solution Explanation: Building a Binary Expression Tree from Infix Expression

This problem requires constructing a binary expression tree from an infix expression string. The solution involves parsing the infix expression and building the tree recursively. The challenge lies in handling operator precedence and correctly associating operands with operators.

Approach:

The most efficient approach uses a recursive, post-order traversal-like method. We can utilize a stack to manage operators and operands during parsing.

  1. Parsing: The input string is parsed from left to right. Numbers are treated as operands, and operators (+, -, *, /) as operators. Parentheses define the order of operations.

  2. Recursive Tree Building: The core logic resides in a recursive function. This function identifies the main operator in a given subexpression (considering parentheses). It then recursively builds the left and right subtrees for the operands around that operator. This step effectively handles operator precedence.

  3. Stack for Operators: A stack is used to manage operator precedence. When an operator is encountered, it's compared to the top of the stack. Higher precedence operators (or operators encountered within parentheses) are pushed onto the stack, ensuring that operations are performed in the correct order.

  4. Base Cases for Recursion: The recursion ends when a number (operand) is encountered. It creates a leaf node representing this operand.

Time and Space Complexity:

  • Time Complexity: O(N), where N is the length of the infix expression string. Each character in the string is processed once during parsing and tree construction. The recursive calls have a depth proportional to the nesting level of parentheses, which is generally considered to be less than or equal to N.

  • Space Complexity: O(N) in the worst case. The space is primarily used by the recursive call stack, which can grow to a depth proportional to the nesting level of parentheses in the expression. Additionally, the tree itself uses space proportional to the number of nodes, which is again related to N.

Code Implementation (Python):

class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
 
def buildTree(s):
    tokens = tokenize(s)  # Helper to split string into tokens
    stack = []
    
    def build(i):
        if i >= len(tokens):
            return None
 
        if isinstance(tokens[i], int):  # Operand
            return Node(tokens[i])
            
        if tokens[i] == '(':
            j = i+1
            cnt = 1
            while j < len(tokens) and cnt > 0:
                if tokens[j] == '(':
                    cnt += 1
                elif tokens[j] == ')':
                    cnt -= 1
                j += 1
            left = build(i + 1)
            right = build(j)
            root = Node(tokens[i + cnt])
            root.left = left
            root.right = right
            return root
        
        #handling other operators
        else:
            left = build(i)
            right = build(i + 1)
            root = Node(tokens[i])
            root.left = left
            root.right = right
            return root
 
    root = build(0)
    return root
 
def tokenize(s):
    tokens = []
    i = 0
    while i < len(s):
        if s[i].isdigit():
            j = i
            while j < len(s) and s[j].isdigit():
                j += 1
            tokens.append(int(s[i:j]))
            i = j
        elif s[i] in ['+', '-', '*', '/', '(', ')']:
            tokens.append(s[i])
            i += 1
        else:
            i += 1  # Ignore spaces and other characters
    return tokens
 
# Example usage
s = "3*4-2*5"
root = buildTree(s)
#You would need to add a function to perform inorder traversal and verify the tree
 

Note: This Python code provides the core recursive tree-building functionality. You'd need to add functions for inorder traversal to verify that the tree correctly produces the original infix expression and a function to handle the case of other operators(not just +,-,*,/). The tokenize helper function cleanly splits the input string into tokens (operands and operators). Error handling (e.g., for invalid input) could be added for robustness. The other languages (Java, C++, Go) would follow a similar structure, adapting syntax and data structures to their respective language conventions.