Belajar DSA tanpa roadmap seperti berlayar tanpa kompas — kita mungkin menguasai satu topik dalam-dalam tetapi melewatkan prasyarat yang dibutuhkan topik lain. Roadmap belajar yang baik menjawab tiga pertanyaan: di mana posisi kita sekarang, ke mana ingin sampai, dan urutan apa yang paling efisien. Pada Chapter ini kita akan membangun roadmap planner yang menggunakan topological sort untuk menentukan urutan belajar berdasarkan prasyarat, lalu mengalokasikan topik ke minggu berdasarkan estimasi jam belajar. Tujuan akhirnya: kita memiliki rencana 3 bulan yang realistis, bukan janji manis “belajar semua DSA dalam 30 hari”.
Tiga Fase Menyusun Roadmap #
Roadmap yang efektif tidak dimulai dari daftar topik, melainkan dari self-assessment dan goal-setting. Setelah jelas posisi dan tujuan, baru kita susun urutan belajar.
| Fase | Pertanyaan yang Dijawab | Output |
|---|---|---|
| Self-assessment | Apa yang sudah saya kuasai? | Level per topik |
| Set goals | Untuk apa belajar DSA? | Target konkret |
| Sequence topics | Urutan belajar yang efisien? | Topik terurut |
| Allocate time | Berapa jam per minggu, berapa lama? | Plan mingguan |
| Execute & track | Apakah saya on track? | Progress tracker |
Self-Assessment: Mengukur Titik Awal #
Sebelum merencanakan, kita harus jujur menilai kemampuan saat ini. Untuk setiap topik, beri penilaian:
| Level | Definisi | Indikator |
|---|---|---|
| 0 — Belum | Tidak pernah dengar | Tidak tahu istilah |
| 1 — Pemula | Tahu konsep, tidak bisa implement | Bisa jelaskan, tidak bisa coding |
| 2 — Menengah | Bisa implement dasar | Selesai soal easy LeetCode |
| 3 — Mahir | Bisa variasi & optimasi | Selesai soal medium |
| 4 — Ahli | Bisa kreatif kombinatorial | Selesai soal hard, ajukan solusi baru |
Contoh hasil self-assessment (sebelum memulai roadmap):
| Topik | Level Awal | Target Level |
|---|---|---|
| Array | 2 | 4 |
| Linked List | 1 | 3 |
| Hash Map | 2 | 4 |
| Tree | 1 | 3 |
| Graph | 0 | 3 |
| DP | 0 | 2 |
Gap antara level awal dan target menentukan estimasi jam belajar per topik.
Set Goals: Tujuan Konkret #
Tujuan “mahir DSA” tidak actionable. Ganti dengan tujuan SMART (Specific, Measurable, Achievable, Relevant, Time-bound):
| Tujuan Vague | Tujuan SMART |
|---|---|
| Mahir DSA | Selesaikan 100 soal LeetCode dalam 3 bulan |
| Bisa interview | Lolos technical interview di FAANG dalam 6 bulan |
| Paham graph | Bila diber soal shortest path, selesai dalam 30 menit |
| Jago CP | Naik ke Codeforces Div 2 (1600 rating) dalam 1 tahun |
| Belajar untuk skripsi | Implementasi graph algo untuk capstone dalam 2 bulan |
Sequence Topics: Topological Sort untuk Belajar #
Topik DSA memiliki dependensi: belajar graph membutuhkan hashing (untuk adjacency list), tree (untuk traversal), dan stack/queue (untuk DFS/BFS). Topological sort memberi urutan belajar yang menghormati prasyarat — sama seperti ketika kita menjadwalkan task dengan dependensi pada Chapter 28.3.
Aturan #
Setiap topik adalah node; edge A → B berarti A adalah prasyarat B. Topological sort menghasilkan urutan valid di mana setiap topik muncul setelah semua prasyaratnya. Komparator sekunder (difficulty, alphabetic) memilih topik yang lebih mudah atau alphabetic lebih kecil bila beberapa topik sama-sama siap.
Mekanisme di Balik Layar #
Kita gunakan algoritma Kahn (Chapter 14) dengan priority queue berbasis difficulty. Topik dengan difficulty rendah keluar lebih dulu — membangun kepercayaan diri sebelum menantang diri dengan topik sulit.
Kode: Roadmap Planner #
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iomanip>
#include <queue>
using namespace std;
struct Topic {
string slug;
string title;
int difficulty; // 1=mudah, 2=menengah, 3=sulit
int est_hours; // estimasi jam belajar
vector<string> prereq;
};
class RoadmapPlanner {
public:
void addTopic(const Topic& t) {
topics_[t.slug] = t;
}
// Topological sort berdasarkan prerequisite (Kahn)
vector<string> topoSort() {
unordered_map<string,int> in_deg;
unordered_map<string, vector<string>> adj;
for (const auto& kv : topics_) {
in_deg[kv.first] = kv.second.prereq.size();
for (const auto& p : kv.second.prereq) {
adj[p].push_back(kv.first);
}
}
// priority_queue: difficulty rendah dulu, alphabetic tie-break
auto cmp = [this](const string& a, const string& b) {
int da = topics_[a].difficulty;
int db = topics_[b].difficulty;
if (da != db) return da > db;
return a > b;
};
priority_queue<string, vector<string>, decltype(cmp)> ready(cmp);
for (const auto& kv : in_deg) {
if (kv.second == 0) ready.push(kv.first);
}
vector<string> order;
while (!ready.empty()) {
string cur = ready.top(); ready.pop();
order.push_back(cur);
for (const auto& next : adj[cur]) {
if (--in_deg[next] == 0) ready.push(next);
}
}
return order;
}
// Alokasi topik ke minggu (kapasitas jam per minggu)
void planWeekly(int hours_per_week, int total_weeks) {
auto order = topoSort();
cout << "=== Roadmap Belajar DSA ===\n";
cout << "Estimasi " << hours_per_week << " jam/minggu, "
<< total_weeks << " minggu total\n\n";
int week = 1;
int used = 0;
cout << "Minggu " << week << ":\n";
for (const auto& slug : order) {
const Topic& t = topics_[slug];
if (used + t.est_hours > hours_per_week && used > 0) {
cout << " (subtotal: " << used << " jam)\n\n";
week++;
if (week > total_weeks) {
cout << "... (sisanya tidak muat, perluas total_weeks)\n";
break;
}
cout << "Minggu " << week << ":\n";
used = 0;
}
cout << " [" << difficultyLabel(t.difficulty) << "] "
<< left << setw(28) << t.title
<< " (" << t.est_hours << " jam)\n";
used += t.est_hours;
}
if (week <= total_weeks && used > 0) {
cout << " (subtotal: " << used << " jam)\n";
}
cout << "\nTotal topik: " << order.size()
<< ", total jam: " << totalHours() << "\n";
}
private:
unordered_map<string, Topic> topics_;
int totalHours() const {
int s = 0;
for (const auto& kv : topics_) s += kv.second.est_hours;
return s;
}
static string difficultyLabel(int d) {
switch (d) {
case 1: return "MUDAH";
case 2: return "MENENGAH";
case 3: return "SULIT";
default: return "?";
}
}
};
int main() {
RoadmapPlanner plan;
plan.addTopic({"array", "Array & Dynamic Array", 1, 4, {}});
plan.addTopic({"string", "String & Basic Matching", 1, 3, {}});
plan.addTopic({"linked-list", "Linked List", 1, 4, {}});
plan.addTopic({"stack", "Stack", 1, 3, {"array"}});
plan.addTopic({"queue", "Queue", 1, 3, {"array"}});
plan.addTopic({"hashing", "Hashing & Hash Map", 2, 6, {"array"}});
plan.addTopic({"sorting", "Sorting Algorithms", 2, 8, {"array"}});
plan.addTopic({"searching", "Searching", 1, 4, {"array"}});
plan.addTopic({"tree", "Binary Tree", 2, 8, {"linked-list", "stack"}});
plan.addTopic({"heap", "Heap & Priority Queue", 2, 6, {"array", "tree"}});
plan.addTopic({"graph", "Graph Representation", 2, 6, {"hashing"}});
plan.addTopic({"bfs-dfs", "BFS & DFS", 2, 8, {"graph", "stack", "queue"}});
plan.addTopic({"shortest-path", "Shortest Path (Dijkstra)", 3, 10, {"heap", "bfs-dfs"}});
plan.addTopic({"greedy", "Greedy Algorithms", 2, 6, {"sorting", "heap"}});
plan.addTopic({"dp", "Dynamic Programming", 3, 12, {"array", "recursion"}});
plan.addTopic({"recursion", "Recursion & Backtracking", 2, 8, {"stack", "tree"}});
plan.planWeekly(6, 12);
return 0;
}Output yang Dihasilkan:
=== Roadmap Belajar DSA ===
Estimasi 6 jam/minggu, 12 minggu total
Minggu 1:
[MUDAH] Array & Dynamic Array (4 jam)
(subtotal: 4 jam)
Minggu 2:
[MUDAH] Linked List (4 jam)
(subtotal: 4 jam)
Minggu 3:
[MUDAH] Queue (3 jam)
(subtotal: 3 jam)
Minggu 4:
[MUDAH] Searching (4 jam)
(subtotal: 4 jam)
Minggu 5:
[MUDAH] Stack (3 jam)
[MUDAH] String & Basic Matching (3 jam)
(subtotal: 6 jam)
Minggu 6:
[MENENGAH] Hashing & Hash Map (6 jam)
(subtotal: 6 jam)
Minggu 7:
[MENENGAH] Graph Representation (6 jam)
(subtotal: 6 jam)
Minggu 8:
[MENENGAH] BFS & DFS (8 jam)
(subtotal: 8 jam)
Minggu 9:
[MENENGAH] Sorting Algorithms (8 jam)
(subtotal: 8 jam)
Minggu 10:
[MENENGAH] Binary Tree (8 jam)
(subtotal: 8 jam)
Minggu 11:
[MENENGAH] Heap & Priority Queue (6 jam)
(subtotal: 6 jam)
Minggu 12:
[MENENGAH] Greedy Algorithms (6 jam)
(subtotal: 6 jam)
... (sisanya tidak muat, perluas total_weeks)
Total topik: 16, total jam: 99Bedah Kode Baris-per-Baris #
struct Topic { string slug; string title; int difficulty; int est_hours; vector<string> prereq; }: setiap topik memiliki identifier (slug), judul deskriptif, tingkat kesulitan, estimasi waktu, dan daftar prasyarat. Model data ini mendukung berbagai macam roadmap — penggunaan kembali untuk tujuan berbeda.unordered_map<string,int> in_deg;: hitung jumlah prasyarat yang belum dipelajari untuk setiap topik. Topik denganin_deg = 0siap dipelajari.adj[p].push_back(kv.first);: adjacency list. Edgep → kv.firstberartipadalah prasyarat darikv.first. Saatpselesai, decrement in-degree semua dependen.auto cmp = [this](const string& a, const string& b) { ... }: comparator priority queue. Lambda menangkapthisagar bisa membacatopics_[a].difficulty. Karena priority queue default adalah max-heap (pop tertinggi dulu), kita returntruesaatakurang prioritas (difficulty lebih tinggi, atau alphabetic lebih besar) — sehingga difficulty rendah keluar lebih dulu.priority_queue<string, vector<string>, decltype(cmp)> ready(cmp);: priority queue dengan comparator lambda.decltype(cmp)mendapatkan tipe comparator tanpa harus menulis struct terpisah.if (used + t.est_hours > hours_per_week && used > 0): cek apakah topik berikutnya muat di minggu ini. Bila tidak, mulai minggu baru. Kondisiused > 0mencegah topik pertama di minggu kosong langsung pindah ke minggu berikutnya (topik bisa lebih besar darihours_per_week).week > total_weeks: bila sudah melebihi target minggu, hentikan alokasi. Sisa topik menjadi “tugas lanjutan”.if (week <= total_weeks && used > 0): setelah loop, cetak subtotal untuk minggu terakhir yang sedang berjalan.
Sample 3-Month Roadmap #
Berdasarkan output kode di atas, berikut roadmap 3 bulan (12 minggu) yang realistis untuk belajar 6 jam/minggu:
| Bulan | Fokus | Topik |
|---|---|---|
| Bulan 1 | Fondasi | Array, Linked List, Queue, Searching, Stack, String |
| Bulan 2 | Struktur Inti | Hashing, Graph Representation, BFS/DFS, Sorting |
| Bulan 3 | Lanjutan | Tree, Heap, Greedy (lanjutan DP & Dijkstra di bulan 4+) |
| Bulan | Aktivitas | Output |
|---|---|---|
| 1 | Belajar konsep + 30 soal easy | Skill dasar solid |
| 2 | Implementasi + 40 soal easy/medium | Pemahaman struktur data |
| 3 | Soal medium + 1 mini project | Aplikasi terapan |
| 4+ | Lanjutan (DP, shortest path) | Persiapan interview/CP |
Tracking Progress #
Roadmap tanpa tracking adalah wishful thinking. Gunakan spreadsheet atau app khusus (mis. Notion, Obsidian) untuk mencatat:
| Metric | Cara Track | Target |
|---|---|---|
| Jam belajar per minggu | Timer (Toggl, Forest app) | ≥ target roadmap |
| Soal selesai | Counter LeetCode/Codeforces | 5–10/minggu |
| Tingkat penguasaan | Self-assessment bulanan | Naik 1 level per bulan |
| Review | Setiap akhir minggu | Catat apa yang sulit |
| Refleksi bulanan | Apakah masih sesuai tujuan? | Adjust bila perlu |
Adaptasi Selama Eksekusi #
Roadmap bukan kontrak — bila satu topik ternyata lebih sulit dari estimasi, perpanjang waktu atau cari materi pendukung. Tanda-tanda roadmap perlu disesuaikan:
| Sinyal | Tindakan |
|---|---|
| Stuck > 2 minggu di satu topik | Cari materi alternatif, minta bantuan, atau mundur ke prasyarat |
| Terlalu cepat selesai (seminggu sisa 3 jam) | Tambah soal latihan atau naik ke topik berikutnya |
| Tujuan berubah (mis. mendapat interview) | Reprioritisasi: fokus topik yang sering muncul di interview |
| Bosok / burnout | Istirahat 1 minggu, evaluasi ulang target |
| Skill gap di luar DSA | Sisipkan topik tambahan (mis. system design untuk interview senior) |
Ringkasan #
- Roadmap belajar dimulai dari self-assessment dan goal-setting, bukan daftar topik.
- Tujuan SMART (specific, measurable, achievable, relevant, time-bound) lebih efektif dari “mau jago DSA”.
- Topological sort memberi urutan belajar yang menghormati prasyarat.
- Priority queue dengan comparator difficulty memilih topik mudah lebih dulu.
- Alokasi waktu mingguan realistis: 6 jam/minggu × 12 minggu = 72 jam (cukup untuk ~12 topik menengah).
- Review mingguan dan adaptasi adalah kunci — roadmap bukan kontrak kaku.