Pertemuan 13
Universitas Pertahanan RI
Setelah pertemuan ini, mahasiswa mampu:
Heap adalah struktur data berbentuk complete binary tree yang memenuhi heap property.
Heap menyediakan akses ke elemen dengan prioritas tertinggi/terendah dalam O(1)
πΊ Max-Heap
Parent β₯ semua children
Root = Maximum
π» Min-Heap
Parent β€ semua children
Root = Minimum
Semua level terisi penuh kecuali mungkin level terakhir, dan level terakhir diisi dari kiri ke kanan.
| Properti | Nilai |
|---|---|
| Tinggi tree (n node) | βlogβ nβ |
| Jumlah node level h | 2^h |
| Selalu balanced | β Ya |
Properti ini memungkinkan representasi efisien dengan array!
Manakah yang merupakan max-heap yang valid?
A. [50, 40, 30, 35, 25]
B. [50, 60, 30, 35, 25]
Jawaban: A
B tidak valid karena 60 > 50 (child > parent)
Heap dapat disimpan dalam array dengan formula navigasi sederhana:
| Operasi | Formula (index 0-based) | Contoh (i = 1) |
|---|---|---|
| Parent | (i - 1) / 2 |
Parent(1) = 0 |
| Left Child | 2 * i + 1 |
Left(1) = 3 |
| Right Child | 2 * i + 2 |
Right(1) = 4 |
π‘ Tidak perlu pointer! Navigasi tree hanya dengan kalkulasi indeks.
class MaxHeap {
private:
vector<int> heap;
int parent(int i) { return (i - 1) / 2; }
int leftChild(int i) { return 2 * i + 1; }
int rightChild(int i) { return 2 * i + 2; }
public:
bool isEmpty() { return heap.empty(); }
int size() { return heap.size(); }
int getMax() {
if (isEmpty()) throw runtime_error("Heap kosong!");
return heap[0]; // Root = maximum
}
};
Kompleksitas: O(log n)
Insert 95 ke max-heap [90, 85, 70]
Step 1: Tambah 95 di akhir β [90, 85, 70, 95]
Step 2: 95 > 85 (parent)? β Swap β [90, 95, 70, 85]
Step 3: 95 > 90 (parent)? β Swap β [95, 90, 70, 85]
β Selesai! 95 menjadi root baru
void insert(int value) {
// 1. Tambah di akhir
heap.push_back(value);
// 2. Percolate up
int index = heap.size() - 1;
while (index > 0 && heap[index] > heap[parent(index)]) {
swap(heap[index], heap[parent(index)]);
index = parent(index);
}
} // Kompleksitas: O(log n)
Kompleksitas: O(log n)
ExtractMax dari [90, 85, 70, 40, 50]
Step 1: Simpan max = 90
Step 2: Pindah 50 ke root β [50, 85, 70, 40]
Step 3: 50 < 85? β Swap dengan child terbesar β [85, 50, 70, 40]
β Return 90 | Heap valid: [85, 50, 70, 40]
int extractMax() {
if (isEmpty()) throw runtime_error("Heap kosong!");
int maxVal = heap[0]; // Simpan max
heap[0] = heap.back(); // Pindah last ke root
heap.pop_back();
if (!heap.empty()) {
percolateDown(0); // Fix heap property
}
return maxVal;
}
void percolateDown(int index) {
int n = heap.size();
int largest = index;
int left = leftChild(index), right = rightChild(index);
if (left < n && heap[left] > heap[largest]) largest = left;
if (right < n && heap[right] > heap[largest]) largest = right;
if (largest != index) {
swap(heap[index], heap[largest]);
percolateDown(largest); // Rekursi
}
}
Setelah extractMax dari [100, 90, 80, 70, 60, 50, 40], apa hasilnya?
Hint: Pindah 40 ke root, lalu percolate down
Hasil: [90, 70, 80, 40, 60, 50]
40 β swap dengan 90 β swap dengan 70 β selesai
| Pendekatan | Metode | Kompleksitas |
|---|---|---|
| Top-down | Insert satu per satu | O(n log n) |
| Bottom-up (Floyd) | Heapify dari node internal terakhir | O(n) |
π‘ Semua leaf node sudah merupakan heap yang valid (heap dengan 1 elemen). Kita hanya perlu memperbaiki node internal.
Mulai dari node internal terakhir: i = n/2 - 1
Heapify mundur sampai root: i = 0
void buildHeap(vector<int>& arr) {
int n = arr.size();
// Mulai dari node internal terakhir
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
}
void heapify(vector<int>& arr, int n, int index) {
int largest = index;
int left = 2 * index + 1;
int right = 2 * index + 2;
if (left < n && arr[left] > arr[largest]) largest = left;
if (right < n && arr[right] > arr[largest]) largest = right;
if (largest != index) {
swap(arr[index], arr[largest]);
heapify(arr, n, largest);
}
}
Array: [4, 10, 3, 5, 1] β Build max-heap
n=5, mulai dari i = 5/2 - 1 = 1
Heapify(1): 10 > 5, 10 > 1 β tidak berubah
Heapify(0): 4 < 10? Swap! β [10, 4, 3, 5, 1]
Rekursi: 4 < 5? Swap! β [10, 5, 3, 4, 1]
β Hasil: [10, 5, 3, 4, 1]
π Node di level h dari bawah: ~n/2^(h+1)
π Operasi per node level h: maksimal h swap
π Total: Ξ£ (h Γ n/2^(h+1)) = O(n)
π‘ Lebih banyak node di level bawah dengan jarak pendek ke posisi final!
Priority Queue adalah ADT di mana setiap elemen memiliki prioritas, dan elemen dengan prioritas tertinggi selalu diakses lebih dulu.
ADT PriorityQueue:
Data:
- Kumpulan elemen dengan prioritas
Operasi:
- insert(item, priority): Tambah elemen dengan prioritas
- extractMax(): Hapus & kembalikan elemen prioritas tertinggi
- peek(): Lihat elemen prioritas tertinggi tanpa hapus
- isEmpty(): Cek apakah kosong
Implementasi:
- Array tidak terurut: Insert O(1), Extract O(n)
- Array terurut: Insert O(n), Extract O(1)
- HEAP: Insert O(log n), Extract O(log n) β OPTIMAL!
| Aspek | Queue (FIFO) | Priority Queue |
|---|---|---|
| Urutan keluar | First In First Out | Berdasarkan prioritas |
| Dequeue | Elemen tertua | Elemen prioritas tertinggi |
| Insert | O(1) | O(log n) dengan heap |
| Contoh | Antrian kasir | Sistem scheduling task |
Sistem Alert Prioritas
pq.insert(Task("Serangan DDoS", 10));
pq.insert(Task("Login mencurigakan", 7));
pq.insert(Task("Traffic anomaly", 3));
// Proses berdasarkan prioritas
pq.extractMax(); // β "Serangan DDoS" (prioritas 10)
Heap Sort = Build max-heap + Extract max berulang kali
Array: [4, 10, 3, 5, 1]
Phase 1 (Build): β [10, 5, 3, 4, 1]
Phase 2 (Extract):
Swap 10β1, heapify: [5, 4, 3, 1 | 10]
Swap 5β1, heapify: [4, 1, 3 | 5, 10]
Swap 4β3, heapify: [3, 1 | 4, 5, 10]
Swap 3β1: [1 | 3, 4, 5, 10]
β Hasil: [1, 3, 4, 5, 10]
void heapSort(vector<int>& arr) {
int n = arr.size();
// Phase 1: Build max-heap
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// Phase 2: Extract elements one by one
for (int i = n - 1; i > 0; i--) {
swap(arr[0], arr[i]); // Pindah max ke akhir
heapify(arr, i, 0); // Heapify reduced heap
}
}
| Algoritma | Best | Average | Worst | Space | Stable |
|---|---|---|---|---|---|
| Heap Sort | O(n log n) | O(n log n) | O(n log n) | O(1) | β |
| Merge Sort | O(n log n) | O(n log n) | O(n log n) | O(n) | β |
| Quick Sort | O(n log n) | O(n log n) | O(nΒ²) | O(log n) | β |
Heap Sort: worst-case O(n log n) + in-place O(1)
β Gunakan ketika:
β οΈ Pertimbangkan lain:
| Konsep | Deskripsi | Kompleksitas |
|---|---|---|
| Heap | Complete binary tree + heap property | - |
| Max/Min-Heap | Parent β₯/β€ children, root = max/min | - |
| Insert | Tambah di akhir + percolate up | O(log n) |
| Extract | Ambil root, lastβroot + percolate down | O(log n) |
| Peek | Lihat root tanpa hapus | O(1) |
| Build Heap | Floyd's algorithm (bottom-up) | O(n) |
| Priority Queue | ADT dengan akses berdasarkan prioritas | Insert/Extract: O(log n) |
| Heap Sort | Build heap + extract n kali | O(n log n), in-place |
Silakan bertanya atau diskusi
Referensi: Cormen Ch.6 | Weiss Ch.6 | Hubbard Ch.12
Struktur Data dan Algoritma
Pertemuan 13
Β© 2026 - CC BY 4.0