Heap — push ও pop-এর প্রতিটি পরিবর্তন¶
অধ্যায়ের সূচি · সহজ ব্যাখ্যা ও বাস্তব ব্যবহার · অনুশীলন ও সমাধান
Min-heap-এ প্রতিটি parent তার child-দের চেয়ে ছোট বা সমান। Push বা pop-এর পরে এই নিয়ম ভাঙলে একটি পথ ধরে swap করেই ঠিক করি। নিচের tree আর array একই heap-এর দুই রূপ।
flowchart TD
n0["index 0 · value 3"] --> n1["index 1 · value 5"]
n0 --> n2["index 2 · value 4"]
n1 --> n3["index 3 · value 9"]
n1 --> n4["index 4 · value 6"]Array-তে index i-এর parent (i−1)//2; children 2*i+1 ও 2*i+2। কোনো child index array-র বাইরে পড়লে সেই child নেই।
Push 1 — নিচ থেকে উপরে ঠিক করা¶
নতুন value সবশেষে বসালে tree-এর complete shape ঠিক থাকে। তারপর parent-এর সঙ্গে তুলনা করি। প্রতিটি ধাপে highlight করা বাক্সে তুলনা বা swap হচ্ছে।
শুরুর heap
0315243946প্রতিটি parent তার child-এর চেয়ে ছোট বা সমান।
১. শেষে 1 যোগ
0315চিহ্নিত ঘর: 24↑ parent3946চিহ্নিত ঘর: 51↑ newIndex 5-এর parent index 2। 1 < 4, তাই swap লাগবে।
২. 4-এর সঙ্গে swap
চিহ্নিত ঘর: 03↑ parent15চিহ্নিত ঘর: 21↑ new3946541 এখন index 2-এ। তার নতুন parent 3; 1 < 3।
৩. 3-এর সঙ্গে swap; শেষ
চিহ্নিত ঘর: 01↑ root15233946541 root-এ পৌঁছেছে। আর parent নেই; মোট দুইটি swap।
চলার পথ index 5 → 2 → 0। Heap-এর অন্য শাখার 5, 9 ও 6 একবারও সরেনি। Parent ছোট বা সমান হয়ে গেলেও আগে থেমে যেতাম; সব push-এ root পর্যন্ত উঠতে হয় না।
Pop minimum — উপর থেকে নিচে ঠিক করা¶
Root-এর 1 হলো ফেরত দেওয়ার উত্তর। শেষ value 4-কে root-এ এনে শেষ slot বাদ দিই। এভাবে shape ঠিক থাকে, কিন্তু root-এর value ঠিক জায়গায় নাও থাকতে পারে।
১. শেষ value root-এ
চিহ্নিত ঘর: 04↑ rootচিহ্নিত ঘর: 15চিহ্নিত ঘর: 233946Children 5 ও 3-এর মধ্যে ছোটটি 3। 4 > 3, তাই 3-এর সঙ্গে swap।
২. ছোট child-এর সঙ্গে swap
চিহ্নিত ঘর: 0315চিহ্নিত ঘর: 24↑ moved39464 এখন index 2-এ। Child index 5 ও 6 array-র বাইরে, তাই শেষ।
ছোট child কেন বেছে নিই? উপরে ওঠা value-টি দুই child-এরই parent হবে। 5-কে তুললে তার নিচে 3 থেকে যায়; 5 ≤ 3 সত্য নয়। 3-কে তুললেই দুই দিকের নিয়ম মেলে।
আবার pop — এবার উত্তর 3¶
১. 3 সরিয়ে শেষের 6 root-এ
চিহ্নিত ঘর: 06চিহ্নিত ঘর: 15চিহ্নিত ঘর: 2439Children 5 ও 4; ছোট child হলো 4।
২. 4-এর সঙ্গে swap; শেষ
চিহ্নিত ঘর: 0415চিহ্নিত ঘর: 26396-এর আর child নেই। Heap আবার ঠিক আছে।
দুই pop-এ বের হলো 1, তারপর 3। Min-heap থেকে সব value pop করলে ছোট থেকে বড় ক্রমে পাই। n বার pop-এর মোট সময় O(n log n); এটি heap ব্যবহার করে sorting করার একটি পদ্ধতি।
কোন repair কখন লাগে¶
| প্রশ্ন | Sift up | Sift down |
|---|---|---|
| কখন | Push-এর পরে | Root pop করার পরে |
| শুরু | নতুন শেষ slot | শেষ value দিয়ে পূরণ করা root |
| তুলনা | নিজের parent | নিজের দুই child-এর ছোটটি |
| দিক | Root-এর দিকে | Leaf-এর দিকে |
| থামার শর্ত | Parent ছোট বা সমান; অথবা root | Children বড় বা সমান; অথবা leaf |
| সর্বোচ্চ ধাপ | Tree height: O(log n) |
Tree height: O(log n) |
নিজে চেষ্টা করো¶
[3, 5, 4, 9, 6]-এ0push করলে দুইটি swap কোথায় হবে?- একই heap-এ
7push করলে কেন কোনো swap লাগবে না? [2, 5, 3, 9, 6, 8, 4]থেকে দুইবার pop করে প্রতিবারের array লেখো।[9, 4, 7, 1, 3]-এ heapify করো: আগে index 1, তারপর index 0-তে sift down। মূল ব্যাখ্যার trace-এর সঙ্গে মিলিয়ে দেখো।
চলমান tree দেখতে VisuAlgo-এর Binary Heap ব্যবহার করতে পারো।