Pertemuan 07
Universitas Pertahanan RI
Setelah pertemuan ini, mahasiswa mampu:
Rekursi adalah teknik pemrograman di mana sebuah fungsi memanggil dirinya sendiri untuk menyelesaikan masalah.
| Komponen | Fungsi |
|---|---|
| Base Case | Kondisi penghenti rekursi |
| Recursive Case | Pemanggilan fungsi ke dirinya sendiri |
returnType fungsiRekursif(parameter) {
// Base case: kondisi berhenti
if (kondisiBerhenti) {
return nilaiDasar;
}
// Recursive case: pemanggilan diri sendiri
return fungsiRekursif(parameterYangLebihKecil);
}
โ ๏ธ Penting: Tanpa base case, rekursi akan berjalan selamanya (infinite recursion) โ Stack Overflow!
int faktorial(int n) {
// Base case
if (n <= 1) {
return 1;
}
// Recursive case
return n * faktorial(n - 1);
}
// faktorial(5) โ 5 ร 4 ร 3 ร 2 ร 1 = 120
๐
Visualisasi Tracing faktorial(5)
images/p07-01-factorial-tracing.png
Call stack turun (pemanggilan) lalu naik (return values)
| Call | n | Kondisi | Return |
|---|---|---|---|
| faktorial(5) | 5 | n > 1 | 5 ร 24 = 120 |
| faktorial(4) | 4 | n > 1 | 4 ร 6 = 24 |
| faktorial(3) | 3 | n > 1 | 3 ร 2 = 6 |
| faktorial(2) | 2 | n > 1 | 2 ร 1 = 2 |
| faktorial(1) | 1 | Base case! | 1 |
Recurrence Relation adalah persamaan yang mendefinisikan kompleksitas waktu fungsi rekursif.
T(n) = aยทT(n/b) + f(n)
T(n) = waktu untuk masalah berukuran na = jumlah subproblemn/b = ukuran setiap subproblemf(n) = waktu membagi dan menggabungkan๐ฒ
Recursion Tree: T(n) = 2T(n/2) + n
images/p07-02-recursion-tree.png
Total cost = n ร (logโn + 1) = O(n log n)
Untuk T(n) = aT(n/b) + f(n), bandingkan f(n) dengan n^(log_b(a)):
| Kasus | Kondisi | Kompleksitas |
|---|---|---|
| 1 | f(n) < n^(log_b(a)) | ฮ(n^(log_b(a))) |
| 2 | f(n) = n^(log_b(a)) | ฮ(n^(log_b(a)) ยท log n) |
| 3 | f(n) > n^(log_b(a)) | ฮ(f(n)) |
๐
Flowchart penggunaan Master Theorem
images/p07-03-master-theorem.png
Langkah 1: Identifikasi
Langkah 2: Hitung
Langkah 3: Bandingkan
T(n) = ฮ(nยฒ)
Ini adalah kompleksitas Merge Sort!
T(n) = ฮ(n log n)
Tail Recursion adalah rekursi di mana pemanggilan rekursif adalah operasi terakhir sebelum return.
โ Non-tail:
return n * faktorial(n-1);
// Operasi ร SETELAH rekursi
โ Tail:
return faktorialTail(n-1, n*acc);
// Rekursi adalah TERAKHIR
๐
Regular vs Tail Recursion Stack
images/p07-04-tail-recursion.png
| Aspek | Regular | Tail |
|---|---|---|
| Memory | O(n) | O(1)* |
| Stack Overflow | Mungkin | Dihindari |
*dengan Tail Call Optimization (TCO)
int faktorialTail(int n, int acc = 1) {
if (n <= 1) return acc; // Base: return accumulator
return faktorialTail(n-1, n*acc); // Tail recursive
}
// Tracing faktorialTail(5, 1):
// (5, 1) โ (4, 5) โ (3, 20) โ (2, 60) โ (1, 120) โ 120
Memoization adalah teknik menyimpan hasil komputasi untuk menghindari perhitungan berulang.
Masalah dengan Fibonacci naive:
// O(2^n) - sangat lambat!
int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2); // Banyak duplikasi!
}
๐ฒ
Fibonacci(5) dengan perhitungan duplikat
images/p07-05-fibonacci-overlap.png
fib(3) dihitung 2 kali, fib(2) dihitung 3 kali!
unordered_map<int, long long> memo;
long long fibMemo(int n) {
if (n <= 1) return n;
// Cek apakah sudah pernah dihitung
if (memo.find(n) != memo.end()) {
return memo[n]; // Return dari cache
}
// Hitung dan simpan
memo[n] = fibMemo(n-1) + fibMemo(n-2);
return memo[n];
}
| Metode | Waktu | Ruang | Fib(40) |
|---|---|---|---|
| Naive | O(2^n) | O(n) | ~1 menit |
| Memoization | O(n) | O(n) | < 1 ms |
| Tail Recursive | O(n) | O(1)* | < 1 ms |
*dengan TCO
Divide-and-Conquer memecah masalah menjadi sub-masalah yang lebih kecil, menyelesaikan secara rekursif, lalu menggabungkan solusi.
1๏ธโฃ
DIVIDE
Bagi masalah
2๏ธโฃ
CONQUER
Selesaikan rekursif
3๏ธโฃ
COMBINE
Gabungkan solusi
โ๏ธ
Divide โ Conquer โ Combine
images/p07-06-divide-conquer.png
| Algoritma | Divide | Conquer | Combine | T(n) |
|---|---|---|---|---|
| Binary Search | Bagi 2 | Search separuh | - | O(log n) |
| Merge Sort | Bagi 2 | Sort keduanya | Merge | O(n log n) |
| Quick Sort | Partition | Sort keduanya | - | O(n log n)* |
| Tower of Hanoi | n-1 disk | Pindah 1 | n-1 disk | O(2^n) |
*average case
Binary Search mencari pada array terurut dengan membagi search space menjadi setengah setiap iterasi.
โ ๏ธ Prasyarat: Array HARUS sudah terurut!
int binarySearch(int arr[], int left, int right, int target) {
if (left > right) return -1; // Base: tidak ditemukan
// Divide: hitung titik tengah
int mid = left + (right - left) / 2;
// Conquer
if (arr[mid] == target)
return mid;
else if (target < arr[mid])
return binarySearch(arr, left, mid-1, target);
else
return binarySearch(arr, mid+1, right, target);
}
Recurrence: T(n) = T(n/2) + O(1)
Master Theorem:
T(n) = ฮ(log n)
๐ผ
Tower of Hanoi dengan 3 disk
images/p07-07-tower-of-hanoi.png
Aturan: 1) Satu disk per waktu, 2) Tidak boleh besar di atas kecil, 3) Gunakan tiang bantu
Jumlah Langkah: 2n - 1
void hanoi(int n, char src, char dst, char aux) {
if (n == 1) {
cout << "Pindah disk 1: " << src << " โ " << dst << endl;
return;
}
// Pindahkan n-1 disk ke auxiliary
hanoi(n-1, src, aux, dst);
// Pindahkan disk terbesar ke destination
cout << "Pindah disk " << n << ": " << src << " โ " << dst << endl;
// Pindahkan n-1 disk ke destination
hanoi(n-1, aux, dst, src);
}
| n (disk) | Langkah | Waktu (1 langkah/detik) |
|---|---|---|
| 3 | 7 | 7 detik |
| 5 | 31 | 31 detik |
| 10 | 1.023 | ~17 menit |
| 20 | 1.048.575 | ~12 hari |
| 64 | ~1.8 ร 10ยนโน | ~585 miliar tahun! |
| Aspek | Rekursi | Iterasi + Stack |
|---|---|---|
| Kode | Lebih sederhana | Lebih kompleks |
| Stack | Implisit (call stack) | Eksplisit |
| Stack Overflow | Risiko tinggi | Dapat dikontrol |
| Efisiensi | Function call overhead | Lebih efisien |
int faktorialStack(int n) {
stack<int> s;
// Push semua nilai (simulasi rekursi turun)
while (n > 1) {
s.push(n);
n--;
}
// Pop dan kalikan (simulasi rekursi naik)
int result = 1;
while (!s.empty()) {
result *= s.top();
s.pop();
}
return result;
}
| Topik | Konsep Kunci | Kompleksitas |
|---|---|---|
| Rekursi | Base case + Recursive case | Tergantung algoritma |
| Master Theorem | 3 kasus berdasarkan f(n) | - |
| Tail Recursion | Rekursi operasi terakhir | O(1) space* |
| Memoization | Simpan hasil yang sudah dihitung | O(2^n) โ O(n) |
| Binary Search | Bagi search space setengah | O(log n) |
| Tower of Hanoi | Pindah n-1, pindah 1, pindah n-1 | O(2^n) |
*dengan TCO
Tentukan kompleksitas T(n) = 8T(n/2) + nยฒ menggunakan Master Theorem.
Jawaban:
Berapa langkah minimum Tower of Hanoi dengan 6 disk?
Jawaban:
Langkah = 2n - 1 = 26 - 1 = 64 - 1 = 63 langkah
Mengapa memoization efektif untuk Fibonacci tapi tidak untuk faktorial?
Binary Search:
Divide-and-Conquer:
Silakan bertanya atau diskusi
Referensi: Cormen Ch.4 | Weiss Ch.1.3 | Hubbard Ch.4
Struktur Data dan Algoritma
Pertemuan 07: Rekursi Lanjut dan Divide-and-Conquer
ยฉ 2026 - CC BY 4.0