Expression trees are a type of binary tree used to represent arithmetic expressions. In an expression tree, each node represents an operator or operand, and the tree's structure reflects the order of operations within the expression. These trees provide a structured way to evaluate and manipulate arithmetic expressions.
In an expression tree, each node can be either an operator or an operand. The operator nodes represent arithmetic operations such as addition, subtraction, multiplication, and division. The operand nodes represent the numeric values or variables in the expression.
The node structure typically contains three fields:
for example the tree for the infix notation
To construct an expression tree from an arithmetic expression, we typically use one of two approaches: prefix notation (also known as Polish notation) or postfix notation (also known as Reverse Polish notation).
In prefix notation, the operator is placed before its operands. To construct an expression tree in prefix notation, we follow these steps:
In postfix notation, the operator is placed after its operands. To construct an expression tree in postfix notation, we follow these steps:
Infix notation is the commonly used arithmetic notation, where operators are placed between their operands. However, infix notation can be ambiguous when it comes to determining the order of operations. To eliminate this ambiguity, we can convert infix expressions to postfix or prefix notation.
To convert an infix expression to postfix notation, we can use the shunting-yard algorithm. Here are the steps:
To convert an infix expression to prefix notation, we can use a similar algorithm as infix to postfix conversion, but with a few modifications. Here are the steps:
Prefix : An expression is called the prefix expression if the operator appears in the expression before the operands. Simply of the form (operator operand1 operand2).
Example :
Postfix :
Prefix :
Infix :
or
Postfix :
Prefix :
Infix :
def isOperator(x):
if x in ["+", "-", "/", "*"]:
return True
else:
return False
# Convert postfix to Prefix expression
def postToPre(post_exp):
s = []
# length of expression
length = len(post_exp)
# reading from right to left
for i in range(length):
# check if symbol is operator
if (isOperator(post_exp[i])):
# pop two operands from stack
op1 = s[-1]
s.pop()
op2 = s[-1]
s.pop()
# concat the operands and operator
temp = post_exp[i] + op2 + op1
# Push string temp back to stack
s.append(temp)
# if symbol is an operand
else:
# push the operand to the stack
s.append(post_exp[i])
ans = ""
for i in s:
ans += i
return ans
# Driver Code
if __name__ == "__main__":
post_exp = "AB+CD-"
# Function call
print("Prefix : ", postToPre(post_exp))
# Example Input
s = "*-A/BC-/AKL"
# Stack for storing operands
stack = []
operators = set(['+', '-', '*', '/', '^'])
# Reversing the order
s = s[::-1]
# iterating through individual tokens
for i in s:
# if token is operator
if i in operators:
# pop 2 elements from stack
a = stack.pop()
b = stack.pop()
# concatenate them as operand1 +
# operand2 + operator
temp = a+b+i
stack.append(temp)
# else if operand
else:
stack.append(i)
# printing final output
print(*stack)
def prefix_to_infix(expression):
stack = []
operators = set(['+', '-', '*', '/', '^'])
for i in range(len(expression)-1, -1, -1):
if expression[i] in operators:
op1 = stack.pop()
op2 = stack.pop()
stack.append('('+op1+expression[i]+op2+')')
else:
stack.append(expression[i])
return stack.pop()
# Driver Code
if __name__ == "__main__":
prefix = "*+AB-CD"
# Function call
print("infix : ", prefix_to_infix(prefix))
def infix_to_prefix(expression):
stack = []
operators = set(['+', '-', '*', '/', '^'])
precedence = {'^': 3, '*': 2, '/': 2, '+': 1, '-': 1}
prefix = ''
for i in range(len(expression)):
if expression[i] == '(':
stack.append('(')
elif expression[i] == ')':
while stack[-1] != '(':
prefix += stack.pop()
stack.pop()
elif expression[i] not in operators:
prefix += expression[i]
else:
while stack and stack[-1] != '(' and precedence[stack[-1]] >= precedence[expression[i]]:
prefix += stack.pop()
stack.append(expression[i])
while stack:
prefix += stack.pop()
return prefix[::-1]
# Driver Code
if __name__ == "__main__":
infix = "(A+B)*(C-D)"
# Function call
print("Prefix : ", infix_to_prefix(infix))
def postfix_to_infix(expression):
stack = []
operators = set(['+', '-', '*', '/', '^'])
for i in range(len(expression)):
if expression[i] in operators:
op2 = stack.pop()
op1 = stack.pop()
stack.append('('+op1+expression[i]+op2+')')
else:
stack.append(expression[i])
return stack.pop()
# Driver Code
if __name__ == "__main__":
postfix = "AB+CD-*"
# Function call
print("infix : ", postfix_to_infix(postfix))
def infix_to_postfix(expression):
stack = []
output = ''
operators = set(['+', '-', '*', '/', '^'])
precedence = {'^': 3, '*': 2, '/': 2, '+': 1, '-': 1}
for i in range(len(expression)):
if expression[i] == '(':
stack.append('(')
elif expression[i] == ')':
while stack[-1] != '(':
output += stack.pop()
stack.pop()
elif expression[i] not in operators:
output += expression[i]
else:
while stack and stack[-1] != '(' and precedence[stack[-1]] >= precedence[expression[i]]:
output += stack.pop()
stack.append(expression[i])
while stack:
output += stack.pop()
return output
# Driver Code
if __name__ == "__main__":
infix = "(A+B)*(C-D)"
# Function call
print("postfix : ", infix_to_postfix(infix))