Stack
Implmentationβ
- For stack implementation
topbegin with-1. - For queue implementation
frontbegin with0andrearbegin with-1.
Infix β Postfix (Shunting Yard using Stack)β
- If operand β add to result
- If
(β push to stack - If
)β pop until( - If operator β pop higher or equal precedence operators first
int precedence(char op) {
if (op == '^') return 3;
if (op == '*' || op == '/') return 2;
if (op == '+' || op == '-') return 1;
return -1;
}
string infixToPostfix(string s) {
stack<char> st;
string result = "";
for (char c : s) {
// If operand
if (isalnum(c)) {
result += c;
}
// If '('
else if (c == '(') {
st.push(c);
}
// If ')'
else if (c == ')') {
while (!st.empty() && st.top() != '(') {
result += st.top();
st.pop();
}
st.pop(); // remove '('
}
// Operator
else {
while (!st.empty() && ((precedence(st.top()) > precedence(ch)) || (precedence(st.top()) == precedence(ch) && ch != '^'))) {
result += st.top();
st.pop();
}
st.push(c);
}
}
while (!st.empty()) {
result += st.top();
st.pop();
}
return result;
}
Stack Traceβ
| Step | Token | Stack | Result |
|---|---|---|---|
| 1 | A | [] | A |
| 2 | + | + | A |
| 3 | B | + | AB |
| 4 | * | + * | AB |
| 5 | ( | + * ( | AB |
| 6 | C | + * ( | ABC |
| 7 | - | + * ( - | ABC |
| 8 | D | + * ( - | ABCD |
| 9 | ) | + * | ABCD- |
| 10 | end | [] | ABCD-*+ |
Infix β Prefixβ
- Reverse string
- Swap
(and) - Convert to Postfix
- Reverse result
string infixToPrefix(string s) {
reverse(s.begin(), s.end());
// Swap brackets
for (char &c : s) {
if (c == '(') c = ')';
else if (c == ')') c = '(';
}
string postfix = infixToPostfix(s);
reverse(postfix.begin(), postfix.end());
return postfix;
}
Why this worksβ
What changes in prefix vs postfix?
The difference is only where the operator appears:
| Notation | Operator position |
|---|---|
| Infix | middle |
| Postfix | end |
| Prefix | start |
Every expression is actually an expression tree:
+
/ \
A *
/ \
B C
Traversals
| Form | Tree traversal |
|---|---|
| Prefix | Preorder (Root β Left β Right) |
| Postfix | Postorder (Left β Right β Root) |
| Infix | Inorder |
Why postfix is easier
- Postfix respects natural evaluation order:
A B C * + - You always see: operands first β operator later. So stack works naturally.
Reverse of infix expression became mirrored. Swapping (, ) make it complete mirror, so perform postorder of the mirror tree, and eventually reverse the mirrorred expression to get the exact result.
Postfix β Infixβ
- If operand β push as string
- If operator β pop two operands
- Form:
(operand1 operator operand2) - Push back
string postfixToInfix(string s) {
stack<string> st;
for (char c : s) {
if (isalnum(c)) {
st.push(string(1, c));
}
else {
string op2 = st.top(); st.pop();
string op1 = st.top(); st.pop();
string temp = "(" + op1 + c + op2 + ")";
st.push(temp);
}
}
return st.top();
}
Prefix β Infixβ
- Traverse from right to left
- Same logic as postfix
string prefixToInfix(string s) {
stack<string> st;
for (int i = s.length() - 1; i >= 0; i--) {
char c = s[i];
if (isalnum(c)) {
st.push(string(1, c));
}
else {
string op1 = st.top(); st.pop();
string op2 = st.top(); st.pop();
string temp = "(" + op1 + c + op2 + ")";
st.push(temp);
}
}
return st.top();
}
Summaryβ
| Conversion | Method Used |
|---|---|
| Infix β Postfix | Stack + Precedence |
| Infix β Prefix | Reverse + Postfix |
| Postfix β Infix | Stack (LβR) |
| Prefix β Infix | Stack (RβL) |
Monotonic Stackβ
A monotonic stack is just a normal stack with one extra rule:
-
Monotonic Increasing Stack: elements are kept in increasing order, else remove it from the container
(bottom β top: small β large)Because when a new element is smaller, it breaks the increasing order β you pop until order is restored.
That popping tells you: βthis new element is the next smaller for those popped elements.β -
Monotonic Decreasing Stack: elements are kept in decreasing order, else remove it from the container
(bottom β top: large β small)Because when a new element is larger, it breaks the decreasing order β you pop.
That popping means: βthis new element is the next greater for those popped elements.β
When a new element breaks the order, we pop elements until the order is restored. The stack will always be sorted.
When you need to handle duplicates, store indices instaead of value.
When processing an element:
- Compare it with stack top
- If it breaks monotonic order β pop
- After popping, push current element
- While popping, we often compute answers