Skip to main content

Stack

Implmentation​

  • For stack implementation top begin with -1.
  • For queue implementation front begin with 0 and rear begin 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​

StepTokenStackResult
1A[]A
2++A
3B+AB
4*+ *AB
5(+ * (AB
6C+ * (ABC
7-+ * ( -ABC
8D+ * ( -ABCD
9)+ *ABCD-
10end[]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:

NotationOperator position
Infixmiddle
Postfixend
Prefixstart

Every expression is actually an expression tree:

      +
/ \
A *
/ \
B C

Traversals

FormTree traversal
PrefixPreorder (Root β†’ Left β†’ Right)
PostfixPostorder (Left β†’ Right β†’ Root)
InfixInorder

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​

ConversionMethod Used
Infix β†’ PostfixStack + Precedence
Infix β†’ PrefixReverse + Postfix
Postfix → InfixStack (L→R)
Prefix → InfixStack (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:

  1. Compare it with stack top
  2. If it breaks monotonic order β†’ pop
  3. After popping, push current element
  4. While popping, we often compute answers