Trees & Binary Search Trees
hierarchical data — search, parse, database-এর ভিত্তি
1. Hierarchies Everywhere
File system, HTML DOM, org chart, parse tree — সবই tree। Binary tree — প্রতিটি node-এর সর্বোচ্চ দুটি child।
2. Node + Traversals
#include <stdio.h>
#include <stdlib.h>
typedef struct T {
int key;
struct T *left, *right;
} T;
T *mk(int k, T *l, T *r) {
T *n = malloc(sizeof *n);
n->key = k; n->left = l; n->right = r;
return n;
}
void inorder (T *r) { if (!r) return; inorder(r->left); printf("%d ", r->key); inorder(r->right); }
void preorder (T *r) { if (!r) return; printf("%d ", r->key); preorder(r->left); preorder(r->right); }
void postorder(T *r) { if (!r) return; postorder(r->left); postorder(r->right); printf("%d ", r->key); }
void free_tree(T *r) { if (!r) return; free_tree(r->left); free_tree(r->right); free(r); }
int main(void) {
T *root = mk(10,
mk(5, mk(3, NULL, NULL), mk(7, NULL, NULL)),
mk(15, NULL, mk(20, NULL, NULL)));
printf("inorder : "); inorder (root); putchar('\n');
printf("preorder : "); preorder (root); putchar('\n');
printf("postorder: "); postorder(root); putchar('\n');
free_tree(root);
return 0;
}
3. BST — Insert & Search
#include <stdio.h>
#include <stdlib.h>
typedef struct T { int key; struct T *l, *r; } T;
T *insert(T *root, int k) {
if (!root) {
T *n = malloc(sizeof *n);
n->key = k; n->l = n->r = NULL;
return n;
}
if (k < root->key) root->l = insert(root->l, k);
else if (k > root->key) root->r = insert(root->r, k);
return root;
}
T *find(T *root, int k) {
if (!root || root->key == k) return root;
return k < root->key ? find(root->l, k) : find(root->r, k);
}
void inorder(T *r) { if (!r) return; inorder(r->l); printf("%d ", r->key); inorder(r->r); }
void free_t (T *r) { if (!r) return; free_t(r->l); free_t(r->r); free(r); }
int main(void) {
T *root = NULL;
int keys[] = {50, 30, 70, 20, 40, 60, 80};
for (int i = 0; i < 7; i++) root = insert(root, keys[i]);
printf("inorder (sorted): "); inorder(root); putchar('\n');
printf("find 40: %s\n", find(root, 40) ? "yes" : "no");
printf("find 45: %s\n", find(root, 45) ? "yes" : "no");
free_t(root);
return 0;
}
লক্ষ্য করুন: BST-র inorder traversal sorted output দিচ্ছে — এটি BST-র মূল property থেকেই স্বাভাবিকভাবে আসে।
4. BST Delete — Three Cases
T *min_node(T *n) { while (n->l) n = n->l; return n; }
T *bst_delete(T *r, int k) {
if (!r) return NULL;
if (k < r->key) r->l = bst_delete(r->l, k);
else if (k > r->key) r->r = bst_delete(r->r, k);
else {
if (!r->l) { T *t = r->r; free(r); return t; }
if (!r->r) { T *t = r->l; free(r); return t; }
T *s = min_node(r->r); // inorder successor
r->key = s->key;
r->r = bst_delete(r->r, s->key);
}
return r;
}
তিনটি case: (ক) leaf — সরাসরি delete; (খ) এক child — child-কে replace করে delete; (গ) দুই child — right subtree-র minimum দিয়ে key replace করে সেই minimum recursively delete।
5. Balance & Why AVL / Red-Black Exist
Skewed BST-তে search O(n)। Balance বজায় রাখার জন্য AVL, Red-Black, B-tree ইত্যাদি। এদের height সবসময় O(log n)।
6. Heaps & Priority Queue
Binary heap — complete binary tree যেখানে parent ≥ children (max-heap)। Compact-ভাবে array-এ রাখা হয়:
// For index i:
// parent = (i - 1) / 2
// left = 2*i + 1
// right = 2*i + 2
#include <stdio.h>
#define CAP 100
static int h[CAP], n = 0;
static void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; }
void push(int x) {
h[n++] = x;
int i = n - 1;
while (i && h[(i - 1) / 2] < h[i]) { swap(&h[(i-1)/2], &h[i]); i = (i-1)/2; }
}
int pop(void) {
int top = h[0];
h[0] = h[--n];
int i = 0;
while (1) {
int l = 2*i + 1, r = 2*i + 2, big = i;
if (l < n && h[l] > h[big]) big = l;
if (r < n && h[r] > h[big]) big = r;
if (big == i) break;
swap(&h[i], &h[big]);
i = big;
}
return top;
}
int main(void) {
int arr[] = {3, 1, 7, 4, 9, 2, 6};
for (int i = 0; i < 7; i++) push(arr[i]);
while (n) printf("%d ", pop()); // 9 7 6 4 3 2 1
putchar('\n');
return 0;
}
Insert (sift-up) ও extract-max (sift-down) দুটিই O(log n)। Heapsort O(n log n), in-place।
7. Practice Problems
- Insert into a BST and print inorder.BST-তে insert করে inorder প্রিন্ট করুন।
✨ Show Answer
Section 3-এর
bst.c-ই উত্তর। - Search a BST.BST-তে search।
✨ Show Answer
Section 3-এর
find-ই উত্তর। - Delete a node (three cases).Node delete — তিনটি case।
✨ Show Answer
Section 4-এর
bst_delete-ই উত্তর। - Find the height of a tree.Tree-র height।
✨ Show Answer
int height(T *r) { if (!r) return -1; int a = height(r->l), b = height(r->r); return 1 + (a > b ? a : b); } - Count total nodes.মোট node গুনুন।
✨ Show Answer
count(r) = r ? 1 + count(r->l) + count(r->r) : 0; - Count leaves only.শুধু leaf গুনুন।
✨ Show Answer
int leaves(T *r) { if (!r) return 0; if (!r->l && !r->r) return 1; return leaves(r->l) + leaves(r->r); } - Level-order traversal with a queue.Queue দিয়ে level-order।
✨ Show Answer
Root enqueue; loop: dequeue → print → left ও right (non-null হলে) enqueue।
- Zig-zag level-order.Zig-zag order।
✨ Show Answer
দুটি stack ব্যবহার করুন — একটি left→right, আরেকটি right→left। প্রতিটি level-এর পর swap।
- Max depth, min depth.সর্বাধিক ও ন্যূনতম depth।
✨ Show Answer
Max:
height-এর মতো। Min: leaf পর্যন্ত সবচেয়ে ছোট path — single-child node সাবধানে। - Check if a tree is a BST.Tree BST কি না যাচাই।
✨ Show Answer
int valid(T *r, long lo, long hi) { if (!r) return 1; if (r->key <= lo || r->key >= hi) return 0; return valid(r->l, lo, r->key) && valid(r->r, r->key, hi); } - Check if a tree is balanced (heights within 1).Balanced tree যাচাই।
✨ Show Answer
প্রতিটি subtree-তে একই সাথে height ও balance ফেরত দিন; কোনোটা unbalanced হলে সরাসরি -1/false।
- LCA in a BST.BST-তে LCA।
✨ Show Answer
T *lca(T *r, int a, int b) { while (r) { if (a < r->key && b < r->key) r = r->l; else if (a > r->key && b > r->key) r = r->r; else return r; } return NULL; } - LCA in a general binary tree.General binary tree-তে LCA।
✨ Show Answer
Recursive: root null বা match হলে root return; left-এ খুঁজুন, right-এ খুঁজুন — দুটোই non-null হলে current root-ই LCA; নতুবা non-null-টি return।
- Find kth smallest in a BST.BST-তে k-th smallest।
✨ Show Answer
Inorder traversal করুন, counter রাখুন, k-তম visit-এই ফিরিয়ে দিন।
- Mirror / invert a binary tree.Binary tree-কে mirror করুন।
✨ Show Answer
void mirror(T *r) { if (!r) return; T *t = r->l; r->l = r->r; r->r = t; mirror(r->l); mirror(r->r); } - Diameter of a tree.Tree-র diameter।
✨ Show Answer
প্রতিটি node-এ
left_height + right_height + 1-এর maximum। Global variable রেখে single pass-এ হিসাব। - Serialize and deserialize a tree.Tree serialize-deserialize।
✨ Show Answer
Preorder + null markers ব্যবহার করুন — e.g.
10,5,N,N,15,N,N। Deserialize preorder-এ recursive। - Build a min-heap; implement push/pop.Min-heap — push/pop।
✨ Show Answer
Section 6-এর max-heap-এ তুলনা উল্টে দিন (
<→>)। - Heapsort an array.Heapsort।
✨ Show Answer
Array থেকে max-heap তৈরি (bottom-up sift-down), তারপর বারবার root pop করে end-এ রাখুন। In-place O(n log n)।
- Top K largest using a min-heap of size K.Min-heap দিয়ে top K।
✨ Show Answer
K-size min-heap maintain করুন। নতুন element যদি heap-top-এর চেয়ে বড় হয়: pop, push। শেষে heap-এ K সবচেয়ে বড় element।
- Merge K sorted arrays using a heap.Heap দিয়ে K sorted array merge।
✨ Show Answer
প্রতিটি array-র head (value, array-id, index) heap-এ রাখুন। বারবার min pop করে next push — O(N log K)।
- Prove: inorder of a BST produces sorted output.প্রমাণ: BST-র inorder sorted।
✨ Show Answer
Induction by tree size. Base: empty/single node — trivially sorted। Step: ধরুন left ও right subtree-এর inorder sorted। Root visit-এর সময়: সব left-key < root-key < সব right-key (BST property)। তাই concat-ও sorted। ∎
Glossary (শব্দকোষ)
| Term | Meaning | বাংলায় |
|---|---|---|
| Tree | A hierarchical, acyclic linked structure. | হায়ারার্কিকাল, cycle-হীন গঠন। |
| Binary Tree | A tree where every node has at most two children. | প্রতিটি node-এর সর্বোচ্চ দুই child। |
| BST (Binary Search Tree) | Binary tree where left < root < right. | Left < root < right সম্পত্তি-সম্পন্ন binary tree। |
| Root | The topmost node. | সবচেয়ে উপরের node। |
| Leaf | A node without children. | Child-হীন node। |
| Internal Node | A node with at least one child. | অন্তত একটি child-যুক্ত node। |
| Depth | Distance from root to a node. | Root থেকে node পর্যন্ত দূরত্ব। |
| Height | Distance from a node to its deepest leaf. | Node থেকে গভীরতম leaf-এর দূরত্ব। |
| Subtree | The tree rooted at any descendant. | Descendant-এ root-করা tree। |
| In-order Traversal | Left → Root → Right (yields sorted order in BST). | Left → Root → Right (BST-তে sorted)। |
| Pre-order Traversal | Root → Left → Right. | Root → Left → Right। |
| Post-order Traversal | Left → Right → Root. | Left → Right → Root। |
| Level-order / BFS | Visit nodes level by level using a queue. | Queue দিয়ে level ধরে ধরে visit। |
| Balanced Tree | Tree where heights of subtrees differ by ≤ 1. | Subtree-এর height-পার্থক্য ≤ 1। |
| Heap | Complete binary tree with parent-child ordering — used for priority queues. | Parent-child ordering-যুক্ত complete tree। |
Summary — Module 27
Tree hierarchical data-র ভিত্তি; BST O(log n) search দেয় (balance থাকলে)। Traversal — pre/in/post (DFS) আর level (BFS)। Heap array-based complete tree, priority queue-এর সেরা choice।