Priority queue memastikan elemen dengan prioritas tertinggi selalu diakses terlebih dahulu. Di episode ini kalian memahami binary heap sebagai representasi array dari complete binary tree, min-heap vs max-heap, operasi insert dan extract dengan bubble up serta heapify down.

Setelah di episode 7 kita memahami hash table — lookup rata-rata O(1) dengan hash function dan collision handling — pada episode ini kita mempelajari priority queue dan binary heap, struktur data di mana akses selalu mengembalikan elemen dengan prioritas tertinggi (atau terendah), bukan yang paling awal dimasukkan seperti queue biasa.
Priority queue bukan hanya konsep teori — ia adalah komponen kritis dari banyak algoritma penting: Dijkstra's shortest path, Huffman coding, task scheduling, dan median streaming. Memahami binary heap sebagai implementasi utama priority queue adalah investasi yang akan membayar berkali-kali di episode selanjutnya.
Priority queue adalah abstraksi di mana setiap elemen memiliki prioritas. Dequeue selalu mengembalikan elemen dengan prioritas tertinggi, bukan yang paling lama dimasukkan.
| Operasi | Kompleksitas | Keterangan |
|---|---|---|
| Insert | O(log n) | Tambah elemen baru |
| Extract-min/max | Ohapus elemen dengan prioritas tertinggi | |
| Peek | O(1) | Lihat elemen tertinggi tanpa menghapus |
Binary heap adalah implementasi paling umum dari priority queue. Ia adalah complete binary tree yang direpresentasikan sebagai array.
Complete binary tree: semua level terisi penuh kecuali level terakhir, yang terisi dari kiri ke kanan.
Untuk node di index i:
(i - 1) // 22 * i + 12 * i + 2Array: [1, 3, 5, 7, 9, 8, 6]
Tree: 1
/ \
3 5
/ \ / \
7 9 8 6Heap property: untuk setiap node, nilainya harus mempertahankan hubungan (≤ untuk min-heap, ≥ untuk max-heap) dengan children-nya.
Tambah elemen di akhir array, lalu "bubble up" — bandingkan dengan parent, tukar jika heap property terlanggar, ulangi sampai posisi benar.
def insert(heap, value):
heap.append(value)
index = len(heap) - 1
while index > 0:
parent = (index - 1) // 2
if heap[index] < heap[parent]:
heap[index], heap[parent] = heap[parent], heap[index]
index = parent
else:
breakAmbil root (minimum), pindahkan elemen terakhir ke root, lalu "heapify down" — bandingkan dengan children, tukar dengan yang lebih kecil, ulangi sampai heap property terpenuhi.
def extract_min(heap):
if len(heap) == 0:
raise IndexError("Heap is empty")
minimum = heap[0]
heap[0] = heap[-1]
heap.pop()
heapify_down(heap, 0)
return minimum
def heapify_down(heap, index):
smallest = index
left = 2 * index + 1
right = 2 * index + 2
if left < len(heap) and heap[left] < heap[smallest]:
smallest = left
if right < len(heap) and heap[right] < heap[smallest]:
smallest = right
if smallest != index:
heap[index], heap[smallest] = heap[smallest], heap[index]
heapify_down(heap, smallest)Membangun heap dari array kosong dengan n insert membutuhkan O(n log n). Tetapi jika kalian sudah punya array penuh, bisa diheapify dalam O(n) dengan memulai dari non-leaf nodes dan heapify down ke atas.
Python menyediakan modul heapq yang sudah teroptimasi:
import heapq
heap = []
heapq.heappush(heap, 5)
heapq.heappush(heap, 1)
heapq.heappush(heap, 3)
print(heapq.heappop(heap))
print(heapq.heappop(heap))
print(heapq.heappop(heap))Note
heapq di Python hanya menyediakan min-heap. Untuk max-heap, negasikan nilai: heappush(heap, -value) dan heappop(heap) lalu negasikan kembali.
Inti yang harus dibawa pulang:
Di episode 9 selanjutnya kita akan membahas deque dan circular buffer — double-ended queue dengan O(1) insert/delete di kedua ujung, sliding window maximum menggunakan monotonic deque, serta implementasi circular buffer fixed-size. Ini adalah episode terakhir di Fase 2 sebelum kita masuk ke Trees!