Stacks & Queues

LIFO ও FIFO — সবখানে ব্যবহৃত

~40 min Advanced 20 practice problems Live code

1. Two Simple Ideas, Huge Impact

  • Stack — LIFO (last in, first out)। প্লেটের স্তূপের মতো।
  • Queue — FIFO (first in, first out)। লাইনে দাঁড়ানো মানুষের মতো।
Function call stack, undo/redo, DFS — সবই stack। BFS, printer job, task scheduler — সবই queue। এই দুটি ছাড়া algorithms-এর জগৎ অসম্পূর্ণ।

2. Array-Based Stack

stack.c
#include <stdio.h>

#define CAP 100

typedef struct { int data[CAP]; int top; } Stack;

int  push(Stack *s, int x)  { if (s->top >= CAP) return 0; s->data[s->top++] = x; return 1; }
int  pop(Stack *s, int *out) { if (s->top == 0) return 0; *out = s->data[--s->top]; return 1; }
int  peek(Stack *s, int *out){ if (s->top == 0) return 0; *out = s->data[s->top - 1]; return 1; }
int  empty(Stack *s)           { return s->top == 0; }

int main(void) {
    Stack s = {.top = 0};
    push(&s, 10); push(&s, 20); push(&s, 30);
    int x;
    while (pop(&s, &x)) printf("%d ", x);   // 30 20 10 (LIFO)
    putchar('\n');
    return 0;
}

সব অপারেশন O(1)। Capacity ছাড়ানোর আগে push-এ return value চেক করতে ভুলবেন না।

3. Circular-Array Queue

queue.c
#include <stdio.h>

#define CAP 100

typedef struct {
    int data[CAP];
    int head, tail, size;
} Queue;

int enqueue(Queue *q, int x) {
    if (q->size == CAP) return 0;
    q->data[q->tail] = x;
    q->tail = (q->tail + 1) % CAP;
    q->size++;
    return 1;
}

int dequeue(Queue *q, int *out) {
    if (q->size == 0) return 0;
    *out = q->data[q->head];
    q->head = (q->head + 1) % CAP;
    q->size--;
    return 1;
}

int main(void) {
    Queue q = {0};
    enqueue(&q, 1); enqueue(&q, 2); enqueue(&q, 3);
    int x;
    while (dequeue(&q, &x)) printf("%d ", x);   // 1 2 3 (FIFO)
    putchar('\n');
    return 0;
}
Circular indexing (% CAP) ব্যবহার করায় অপচয় ছাড়াই array ঘুরিয়ে ব্যবহার করা যায় — ফলে সব অপারেশন সত্যিকারের O(1)।

4. Balanced Parentheses (Stack Application)

balanced.c
#include <stdio.h>
#include <string.h>

int balanced(const char *s) {
    char stk[256]; int top = 0;
    for (; *s; s++) {
        char c = *s;
        if (c == '(' || c == '[' || c == '{') stk[top++] = c;
        else if (c == ')' || c == ']' || c == '}') {
            if (top == 0) return 0;
            char o = stk[--top];
            if ((c == ')' && o != '(') ||
                (c == ']' && o != '[') ||
                (c == '}' && o != '{')) return 0;
        }
    }
    return top == 0;
}

int main(void) {
    const char *tests[] = { "{[()]}", "{[(])}", "((()))", "(]", "" };
    for (int i = 0; i < 5; i++)
        printf("\"%s\" → %s\n", tests[i], balanced(tests[i]) ? "balanced" : "not");
    return 0;
}

5. Postfix Expression Evaluation

postfix.c — stdin: "3 4 + 5 *"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

int main(void) {
    int stk[256]; int top = 0;
    char tok[64];
    while (scanf("%63s", tok) == 1) {
        if (isdigit((unsigned char)tok[0]) ||
            (tok[0] == '-' && isdigit((unsigned char)tok[1]))) {
            stk[top++] = atoi(tok);
        } else {
            int b = stk[--top], a = stk[--top], r = 0;
            switch (tok[0]) {
                case '+': r = a + b; break;
                case '-': r = a - b; break;
                case '*': r = a * b; break;
                case '/': r = b ? a / b : 0; break;
            }
            stk[top++] = r;
        }
    }
    printf("result = %d\n", stk[0]);
    return 0;
}

Postfix 3 4 + 5 * → (3+4)*5 = 35। Operand দেখলে push, operator দেখলে দুটো pop করে result push।

6. Classic Applications

  • Stack: call frame, expression eval, undo/redo, DFS, parenthesis matching, backtracking।
  • Queue: BFS, task scheduler, buffered I/O, keyboard input, printer queue।

7. Practice Problems

  1. Array-based stack with push/pop/peek/empty.
    Array দিয়ে stack বানান।
    ✨ Show Answer

    Section 2-এর stack.c-ই সম্পূর্ণ উত্তর।

  2. Linked-list-based stack.
    Linked list দিয়ে stack বানান।
    ✨ Show Answer
    // push = push_front; pop = remove head.
    // All operations O(1), unbounded size.
  3. Circular-array queue.
    Circular array-তে queue।
    ✨ Show Answer

    Section 3-এর queue.c-ই উত্তর।

  4. Queue using two stacks.
    দুটি stack দিয়ে queue বানান।
    ✨ Show Answer

    Trick: in stack-এ enqueue push; dequeue-এর সময় যদি out stack খালি হয় তাহলে সব in থেকে out-এ pop-push করুন, তারপর out-এর top pop করুন। Amortized O(1)।

  5. Stack using two queues.
    দুটি queue দিয়ে stack বানান।
    ✨ Show Answer

    Push-এর সময়: q2-এ নতুন মান, তারপর q1-এর সব মান q2-এ নিয়ে আসুন, q1 ও q2 swap করুন। Pop = q1-এর front।

  6. Balanced parentheses (multiple bracket types).
    একাধিক ধরনের bracket-সহ balanced check করুন।
    ✨ Show Answer

    Section 4-এর balanced.c-ই উত্তর।

  7. Evaluate a postfix expression.
    Postfix expression evaluate করুন।
    ✨ Show Answer

    Section 5-এর postfix.c-ই উত্তর।

  8. Infix → postfix (Shunting Yard).
    Infix থেকে postfix (Shunting Yard)।
    ✨ Show Answer

    Operand directly output। Operator: stack-এ thাকা উচ্চ-precedence operator আগে output, তারপর নতুনটা push। ( push; ) এলে ( পর্যন্ত pop+output।

  9. Next Greater Element for each in array.
    প্রতিটি element-এর next greater element।
    ✨ Show Answer
    nge.c
    #include <stdio.h>
    int main(void) {
        int a[] = {4, 5, 2, 25, 7, 10};
        int n = 6, stk[6], top = 0;
        int ans[6];
        for (int i = n - 1; i >= 0; i--) {
            while (top && stk[top - 1] <= a[i]) top--;
            ans[i] = top ? stk[top - 1] : -1;
            stk[top++] = a[i];
        }
        for (int i = 0; i < n; i++) printf("%d → %d\n", a[i], ans[i]);
        return 0;
    }
  10. Largest rectangle in a histogram.
    Histogram-এ সবচেয়ে বড় আয়তক্ষেত্র।
    ✨ Show Answer

    Monotonic stack ব্যবহার করুন — প্রতিটি bar-এর জন্য বাম ও ডান নিকটতম ছোট bar-এর index বের করুন। O(n) solution।

  11. Min stack — push/pop/min all O(1).
    O(1) push/pop/min-সহ min stack।
    ✨ Show Answer

    দুটি stack রাখুন — main ও min_stk। Push-এর সময় min_stk-এ current min push। Pop-এর সময় দুটোই pop।

  12. Sort a stack using only stack operations.
    শুধু stack operation দিয়ে stack sort করুন।
    ✨ Show Answer

    Auxiliary stack tmp নিন; src থেকে একটি করে pop করে tmp-র sorted order-এ ঢোকান — প্রয়োজনে tmp থেকে বড় মান src-এ ফেরত পাঠান। O(n²)।

  13. Reverse a queue using a stack.
    Stack দিয়ে queue reverse করুন।
    ✨ Show Answer

    Queue থেকে সব dequeue করে stack-এ push, তারপর stack থেকে pop করে আবার queue-এ enqueue। Order উল্টে যাবে।

  14. Implement a deque (double-ended queue).
    Double-ended queue (deque) বানান।
    ✨ Show Answer

    Circular array-তে head এবং tail দুটোই বাড়ানো/কমানো যায়। Doubly linked list-ও কাজ করে। সব push/pop O(1)।

  15. Sliding window maximum in O(n) using a deque.
    Deque দিয়ে O(n)-এ sliding window maximum।
    ✨ Show Answer

    Deque-এ decreasing order-এ indices রাখুন। নতুন element এলে back থেকে সব ছোট index pop; window-র বাইরে front সরিয়ে দিন। Deque-এর front current window-এর max।

  16. Circular-tour / gas-station problem.
    Circular-tour সমস্যা।
    ✨ Show Answer

    Stations ধরে চলুন, tank-এ total = gas - cost; total negative হলে start সরিয়ে এগিয়ে যান। Greedy O(n) solution।

  17. First non-repeating character in a stream (queue + count).
    Stream-এ প্রথম non-repeating character।
    ✨ Show Answer

    Queue-এ char push; frequency map রাখুন। নতুন char এলে push; front-এর count > 1 হলে pop-করে এগোন। Current front-ই উত্তর।

  18. Simulate a CPU scheduler with round-robin queue.
    Round-robin queue দিয়ে CPU scheduler simulate করুন।
    ✨ Show Answer

    সব process queue-এ ঢোকান; time slice-এর পর process-কে আবার queue-এর শেষে push। Process শেষ না হওয়া পর্যন্ত রিপিট।

  19. Undo/redo buffer with two stacks.
    দুটি stack দিয়ে undo/redo।
    ✨ Show Answer

    undo_stk-এ পূর্ববর্তী states; undo মানে pop করে redo_stk-এ push। Redo উল্টোটা। নতুন action হলে redo_stk খালি করুন।

  20. Why is the program call stack limited to a few MB while the heap can be GBs?
    Call stack-এর size কেন মাত্র কয়েক MB, heap GB?
    ✨ Show Answer

    Stack প্রতি থ্রেডে pre-allocated, contiguous virtual memory region — স্বল্প সময়ে growth-এ page fault/guard page crash দেবে। Heap প্রয়োজনে OS থেকে নতুন page মেলে, fragmentation-সহ বিশাল সাইজ সমর্থন করে। OS limit (ulimit -s) দিয়ে stack বাড়ানো-কমানো যায়।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
StackLIFO container — last in, first out.LIFO container — শেষে আসা প্রথমে যায়।
QueueFIFO container — first in, first out.FIFO container — আগে আসা আগে যায়।
LIFOLast-In-First-Out ordering.শেষে এসেছে — প্রথমে বেরোয়।
FIFOFirst-In-First-Out ordering.প্রথমে এসেছে — প্রথমে বেরোয়।
pushAdd an element to the top of the stack.Stack-এর top-এ element যোগ।
popRemove and return the top of the stack.Top থেকে element সরানো ও ফেরত দেওয়া।
peek / topLook at the top without removing.Top দেখা — সরানো ছাড়া।
enqueueAdd to the rear of the queue.Queue-এর শেষে যোগ।
dequeueRemove from the front of the queue.Queue-এর সামনে থেকে সরানো।
Front / RearThe two ends of a queue.Queue-এর সামনের ও পেছনের প্রান্ত।
Circular BufferQueue implemented in a fixed-size array with wrap-around.Fixed-size array-এ wrap-around-যুক্ত queue।
UnderflowPop/dequeue from an empty container.খালি container থেকে pop/dequeue।
OverflowPushing to a full fixed-size container.Full container-এ push।
DequeDouble-ended queue — insert/remove at both ends.দুই প্রান্তে insert/remove সমর্থনকারী queue।

Summary — Module 26

Stack = LIFO, Queue = FIFO। দুটোর core operation O(1)। DFS/BFS, parser, scheduler — interview-এর frequent টপিক। একবার scratch থেকে লিখে ফেলুন — পরবর্তী সব algorithm module-এ কাজে লাগবে।

Next Module → Trees & Binary Search Trees।