Infix-Postfix
Associativity
Associativity defines the order in which operators of the same
precedence level are evaluated. There are two types of
associativity:
1. Left-to-Right (Left Associative): Operators are evaluated from
left to right.
2. Right-to-Left (Right Associative): Operators are evaluated
from right to left.
Associativity
When you have multiple operators of the same precedence in an
expression, associativity helps determine which operator to
evaluate first.
For example, in an expression like a - b + c, the associativity of +
and - (which have the same precedence) decides whether to
evaluate a - b first or b + c first.
When determining the order of operations, precedence comes
first, and associativity helps break ties between operators of the
same precedence level.
Left-to-Right (Left Associative)
Most operators in programming languages are left associative.
This means that when operators of the same precedence appear
in an expression, they are evaluated from left to right.
For example, a - b – c will be evaluated as:
(a - b) – c
a / b / c will be evaluated as:
(a / b) / c
Right-to-Left (Right Associative)
Some operators, like exponentiation (^) or assignment (=), are
right associative. This means that when operators of the same
precedence level appear in an expression, they are evaluated
from right to left.
For example, a ^ b ^ c will be evaluated as:
a ^ (b ^ c)
a = b = c will be evaluated as:
a = (b = c)
Summary
Left Associative: Operators are evaluated from left to right.
Examples: +, -, *, /
Right Associative: Operators are evaluated from right to left.
Examples: =, ^, ternary (?:)
Infix-Postfix
Infix notation is the common way we write expressions, where
operators are placed between operands, e.g., A + B.
However, computers find it easier to evaluate expressions in
postfix notation (also known as Reverse Polish Notation), where
operators are placed after the operands, e.g., A B +. The
advantage of postfix notation is that it doesn't require
parentheses or operator precedence rules.
Steps
Initialize an empty stack for storing operators and an empty list for the output
(postfix expression).
Scan the infix expression from left to right.
For each symbol in the expression:
Operand: If the symbol is an operand (e.g., a variable or number), append it directly to
the postfix expression.
Left Parenthesis (: Push it onto the stack.
Right Parenthesis ): Pop from the stack and append to the postfix expression until a left
parenthesis is encountered. Discard the left parenthesis.
Operator: If the symbol is an operator:
While there is an operator on the top of the stack with greater or equal precedence (and the
operator is left-associative), pop the operator from the stack and append it to the postfix
expression.
Push the current operator onto the stack.
Pop any remaining operators from the stack and append them to the postfix
expression after the input expression is fully processed.
Example: A + B * (C - D) / E
Initialize the stack (empty) and the postfix list (empty).
Process each character in the infix expression:
A: It's an operand, so append it to the postfix expression.
Postfix: A
Stack: []
+: It's an operator, and the stack is empty, so push it onto the stack.
Postfix: A
Stack: ['+’]
B: It's an operand, so append it to the postfix expression.
Postfix: A B
Stack: ['+']
A + B * (C - D) / E
*: It's an operator, and * has higher precedence than +, so push *
onto the stack.
Postfix: A B
Stack: ['+', '*’]
(: It's a left parenthesis, so push it onto the stack.
Postfix: A B
Stack: ['+', '*', '(‘]
C: It's an operand, so append it to the postfix expression.
Postfix: A B C
Stack: ['+', '*', '(']
A + B * (C - D) / E
-: It's an operator, but because it's inside parentheses, push it onto
the stack.
Postfix: A B C
Stack: ['+', '*', '(', ‘-’]
D: It's an operand, so append it to the postfix expression.
Postfix: A B C D
Stack: ['+', '*', '(', '-']
): It's a right parenthesis, so pop operators from the stack and
append to the postfix expression until a left parenthesis is
encountered. Pop - and append it.
Postfix: A B C D –
Stack: ['+', '*’] We discard the (
A + B * (C - D) / E
/: It's an operator. Since / has higher precedence than + but the same as *,
we pop * (because * and / have the same precedence and left associativity)
and append it to the postfix expression, then push / onto the stack.
Postfix: A B C D - *
Stack: [‘+’, ‘/’]
E: It's an operand, so append it to the postfix expression.
Postfix: A B C D - * E
Stack: [‘+’, ‘/’]
Pop remaining operators from the stack:
Pop / & + and append it to the postfix expression.
Postfix: A B C D - * E / +
Stack: []
Summary of Steps
Operands go directly to the postfix expression.
Operators are pushed onto the stack, but before pushing, pop
operators with greater or equal precedence from the stack to the
postfix expression.
Parentheses help manage precedence inside the expression:
Left parentheses are pushed onto the stack.
Right parentheses cause the stack to be popped until a left parenthesis is
encountered.
At the end, pop all operators left in the stack to the postfix
expression.
Postfix-Infix conversion
Initialize an empty stack.
Scan the postfix expression from left to right.
For each symbol in the postfix expression:
Operand: If the symbol is an operand (e.g., a variable or number),
push it onto the stack.
Operator: If the symbol is an operator:
Pop the top two elements from the stack.
Form an infix expression by combining these two elements with the
operator in between, and add parentheses around the new expression.
Push this new infix expression back onto the stack.
At the end, the stack will contain only one element, which is the
fully converted infix expression.
Example: ABCD+*E/-
Initialize stack: [].
Process the first symbol A:
It is an operand, so push it onto the stack.
Stack: ['A’]
Process the second symbol B:
It is an operand, so push it onto the stack.
Stack: ['A', 'B’]
Process the third symbol C:
It is an operand, so push it onto the stack.
Stack: ['A', 'B', 'C']
ABCD+*E/-
Process the fourth symbol D:
It is an operand, so push it onto the stack.
Stack: ['A', 'B', 'C', 'D’]
Process the fifth symbol +:
It is an operator.
Pop the top two elements: D and C.
Form the infix expression: (C + D).
Push this back onto the stack.
Stack: ['A', 'B', '(C + D)']
ABCD+*E/-
Process the sixth symbol *:
It is an operator.
Pop the top two elements: (C + D) and B.
Form the infix expression: (B * (C + D)).
Push this back onto the stack.
Stack: ['A', '(B * (C + D))’]
Process the seventh symbol E:
It is an operand, so push it onto the stack.
Stack: ['A', '(B * (C + D))', 'E']
ABCD+*E/-
Process the eighth symbol /:
It is an operator.
Pop the top two elements: E and (B * (C + D)).
Form the infix expression: ((B * (C + D)) / E).
Push this back onto the stack.
Stack: ['A', '((B * (C + D)) / E)']
ABCD+*E/-
Process the ninth symbol -:
It is an operator.
Pop the top two elements: ((B * (C + D)) / E) and A.
Form the infix expression: (A - ((B * (C + D)) / E)).
Push this back onto the stack.
Stack: ['(A - ((B * (C + D)) / E))’]
End of the expression: The stack now contains the fully converted
infix expression.
(A - ((B * (C + D)) / E))
Summary
Operands are directly pushed onto the stack.
Operators cause two operands to be popped from the stack, an
infix expression is formed with those operands and the operator,
and the result is pushed back onto the stack.
The first popped operand is the right operand.
The second popped operand is the left operand.
At the end, the stack contains one element, which is the final
infix expression.
Postfix evaluation
Initialize an empty stack.
Scan the postfix expression from left to right.
For each symbol in the postfix expression:
Operand: If the symbol is an operand (a number), push it onto the
stack.
Operator: If the symbol is an operator:
Pop the required number of operands from the stack (usually two for
binary operators).
Apply the operator to the popped operands.
Push the result of the operation back onto the stack.
At the end, the stack will contain only one element, which is the
final result of the expression.
Example: 6 2 3 + - 3 8 2 / + * 2 ^
Initialize the stack: []
Process 6:
It's an operand, so push it onto the stack.
Stack: [6]
Process 2:
It's an operand, so push it onto the stack.
Stack: [6, 2]
Process 3:
It's an operand, so push it onto the stack.
Stack: [6, 2, 3]
623+-382/+*2^
Process +:
It's an operator.
Pop the top two operands (3 and 2), and perform the operation 2 + 3
= 5.
Push the result back onto the stack.
Stack: [6, 5]
Process -:
It's an operator.
Pop the top two operands (5 and 6), and perform the operation 6
- 5 = 1.
Push the result back onto the stack.
Stack: [1]
623+-382/+*2^
Process 3:
It's an operand, so push it onto the stack.
Stack: [1, 3]
Process 8:
It's an operand, so push it onto the stack.
Stack: [1, 3, 8]
Process 2:
It's an operand, so push it onto the stack.
Stack: [1, 3, 8, 2]
623+-382/+*2^
Process /:
It's an operator.
Pop the top two operands (2 and 8), and perform the operation 8 / 2 = 4.
Push the result back onto the stack.
Stack: [1, 3, 4]
Process +:
It's an operator.
Pop the top two operands (4 and 3), and perform the operation 3 + 4 =
7.
Push the result back onto the stack.
Stack: [1, 7]
623+-382/+*2^
Process *:
It's an operator.
Pop the top two operands (7 and 1), and perform the operation 1 * 7
= 7.
Push the result back onto the stack.
Stack: [7]
Process 2:
It's an operand, so push it onto the stack.
Stack: [7, 2]
623+-382/+*2^
Process ^ (exponentiation):
It's an operator.
Pop the top two operands (2 and 7), and perform the operation 7 ^ 2
= 49.
Push the result back onto the stack.
Stack: [49]
End of Expression: The stack now contains the final result.