Stacks & Queues
LIFO ও FIFO — সবখানে ব্যবহৃত
1. Two Simple Ideas, Huge Impact
- Stack — LIFO (last in, first out)। প্লেটের স্তূপের মতো।
- Queue — FIFO (first in, first out)। লাইনে দাঁড়ানো মানুষের মতো।
2. Array-Based Stack
#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
#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;
}
% CAP) ব্যবহার করায় অপচয় ছাড়াই array ঘুরিয়ে ব্যবহার করা যায় — ফলে সব অপারেশন সত্যিকারের O(1)।4. Balanced Parentheses (Stack Application)
#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
#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
- Array-based stack with push/pop/peek/empty.Array দিয়ে stack বানান।
✨ Show Answer
Section 2-এর
stack.c-ই সম্পূর্ণ উত্তর। - Linked-list-based stack.Linked list দিয়ে stack বানান।
✨ Show Answer
// push = push_front; pop = remove head. // All operations O(1), unbounded size. - Circular-array queue.Circular array-তে queue।
✨ Show Answer
Section 3-এর
queue.c-ই উত্তর। - Queue using two stacks.দুটি stack দিয়ে queue বানান।
✨ Show Answer
Trick:
instack-এ enqueue push; dequeue-এর সময় যদিoutstack খালি হয় তাহলে সবinথেকেout-এ pop-push করুন, তারপরout-এর top pop করুন। Amortized O(1)। - Stack using two queues.দুটি queue দিয়ে stack বানান।
✨ Show Answer
Push-এর সময়:
q2-এ নতুন মান, তারপরq1-এর সব মানq2-এ নিয়ে আসুন,q1ওq2swap করুন। Pop =q1-এর front। - Balanced parentheses (multiple bracket types).একাধিক ধরনের bracket-সহ balanced check করুন।
✨ Show Answer
Section 4-এর
balanced.c-ই উত্তর। - Evaluate a postfix expression.Postfix expression evaluate করুন।
✨ Show Answer
Section 5-এর
postfix.c-ই উত্তর। - Infix → postfix (Shunting Yard).Infix থেকে postfix (Shunting Yard)।
✨ Show Answer
Operand directly output। Operator: stack-এ thাকা উচ্চ-precedence operator আগে output, তারপর নতুনটা push।
(push;)এলে(পর্যন্ত pop+output। - 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; } - Largest rectangle in a histogram.Histogram-এ সবচেয়ে বড় আয়তক্ষেত্র।
✨ Show Answer
Monotonic stack ব্যবহার করুন — প্রতিটি bar-এর জন্য বাম ও ডান নিকটতম ছোট bar-এর index বের করুন। O(n) solution।
- 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। - 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²)। - Reverse a queue using a stack.Stack দিয়ে queue reverse করুন।
✨ Show Answer
Queue থেকে সব dequeue করে stack-এ push, তারপর stack থেকে pop করে আবার queue-এ enqueue। Order উল্টে যাবে।
- Implement a deque (double-ended queue).Double-ended queue (deque) বানান।
✨ Show Answer
Circular array-তে head এবং tail দুটোই বাড়ানো/কমানো যায়। Doubly linked list-ও কাজ করে। সব push/pop O(1)।
- 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।
- Circular-tour / gas-station problem.Circular-tour সমস্যা।
✨ Show Answer
Stations ধরে চলুন, tank-এ total = gas - cost; total negative হলে start সরিয়ে এগিয়ে যান। Greedy O(n) solution।
- 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-ই উত্তর।
- Simulate a CPU scheduler with round-robin queue.Round-robin queue দিয়ে CPU scheduler simulate করুন।
✨ Show Answer
সব process queue-এ ঢোকান; time slice-এর পর process-কে আবার queue-এর শেষে push। Process শেষ না হওয়া পর্যন্ত রিপিট।
- Undo/redo buffer with two stacks.দুটি stack দিয়ে undo/redo।
✨ Show Answer
undo_stk-এ পূর্ববর্তী states; undo মানে pop করেredo_stk-এ push। Redo উল্টোটা। নতুন action হলেredo_stkখালি করুন। - 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 (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
| Stack | LIFO container — last in, first out. | LIFO container — শেষে আসা প্রথমে যায়। |
| Queue | FIFO container — first in, first out. | FIFO container — আগে আসা আগে যায়। |
| LIFO | Last-In-First-Out ordering. | শেষে এসেছে — প্রথমে বেরোয়। |
| FIFO | First-In-First-Out ordering. | প্রথমে এসেছে — প্রথমে বেরোয়। |
push | Add an element to the top of the stack. | Stack-এর top-এ element যোগ। |
pop | Remove and return the top of the stack. | Top থেকে element সরানো ও ফেরত দেওয়া। |
peek / top | Look at the top without removing. | Top দেখা — সরানো ছাড়া। |
enqueue | Add to the rear of the queue. | Queue-এর শেষে যোগ। |
dequeue | Remove from the front of the queue. | Queue-এর সামনে থেকে সরানো। |
| Front / Rear | The two ends of a queue. | Queue-এর সামনের ও পেছনের প্রান্ত। |
| Circular Buffer | Queue implemented in a fixed-size array with wrap-around. | Fixed-size array-এ wrap-around-যুক্ত queue। |
| Underflow | Pop/dequeue from an empty container. | খালি container থেকে pop/dequeue। |
| Overflow | Pushing to a full fixed-size container. | Full container-এ push। |
| Deque | Double-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-এ কাজে লাগবে।