BFS & DFS (Graph Traversal) — Algoritma

BFS (Breadth-First Search) dan DFS (Depth-First Search) adalah dua cara dasar menjelajahi graph. Hampir semua algoritma graph lainnya dibangun di atas keduanya.

BFS (Breadth-First Search) dan DFS (Depth-First Search) adalah dua cara dasar menjelajahi graph. Hampir semua algoritma graph lainnya dibangun di atas keduanya.

BFS — Breadth-First Search

BFS menjelajahi graph level demi level — kunjungi semua tetangga langsung dulu, baru tetangga-tetangga dari tetangga. Mirip riak air yang menyebar.

Struktur data kunci: Queue (FIFO)

A L0 B C L1 D E L2

Urutan kunjungan BFS: A, B, C, D, E

function bfs(adj, start) {
  const visited = new Set([start]);
  const queue = [start];
  const order = [];

  while (queue.length > 0) {
    const node = queue.shift(); // ambil depan (FIFO)
    order.push(node);

    for (const neighbor of adj[node]) {
      if (!visited.has(neighbor)) {
        visited.add(neighbor);
        queue.push(neighbor); // tambah ke belakang
      }
    }
  }
  return order;
}

const adj = { A: ["B", "C"], B: ["A", "D"], C: ["A", "E"], D: ["B"], E: ["C"] };
bfs(adj, "A"); // ["A", "B", "C", "D", "E"]

Kegunaan BFS:

DFS — Depth-First Search

DFS menjelajahi sedalam mungkin sebelum mundur (backtrack). Mirip eksplorasi labirin — ikuti satu jalan sampai mentok.

Struktur data kunci: Stack (LIFO) — atau call stack (rekursi)

// Rekursif (paling umum)
function dfs(adj, node, visited = new Set(), order = []) {
  if (visited.has(node)) return order;
  visited.add(node);
  order.push(node);

  for (const neighbor of adj[node]) {
    dfs(adj, neighbor, visited, order);
  }
  return order;
}

// Iteratif dengan stack
function dfsIter(adj, start) {
  const visited = new Set();
  const stack = [start];
  const order = [];

  while (stack.length > 0) {
    const node = stack.pop(); // ambil atas (LIFO)
    if (visited.has(node)) continue;
    visited.add(node);
    order.push(node);

    for (const neighbor of adj[node]) {
      if (!visited.has(neighbor)) stack.push(neighbor);
    }
  }
  return order;
}

Kegunaan DFS:

BFS vs DFS

Fitur BFS DFS
Struktur data Queue Stack (atau rekursi)
Memori O(lebar graph) O(kedalaman graph)
Shortest path (unweighted) Ya Tidak (kecuali brute force)
Topological sort Kahn's (BFS) Natural dengan DFS
Cycle detection Bisa dengan colors Natural
Implementasi Iteratif Rekursi (paling mudah)

Contoh: Shortest Path dengan BFS

// Distance dari start ke semua node (unweighted)
function bfsDistance(adj, start) {
  const dist = { [start]: 0 };
  const queue = [start];

  while (queue.length > 0) {
    const node = queue.shift();
    for (const neighbor of adj[node]) {
      if (!(neighbor in dist)) {
        dist[neighbor] = dist[node] + 1; // level + 1
        queue.push(neighbor);
      }
    }
  }
  return dist;
}

bfsDistance(adj, "A"); // { A: 0, B: 1, C: 1, D: 2, E: 2 }

Kompleksitas (keduanya): O(V + E) — kunjungi tiap node dan edge sekali.

Tip: Jika masalah tentang "jarak terpendek di unweighted graph" → BFS. Jika tentang "jelajahi semua / backtracking" → DFS.

🎭 Analogi sehari-hari (graph context): Pertama kali sampai ke kota baru. Mau eksplorasi.

💡 BFS = shortest path proof: Saat node di-visit pertama kali via BFS, dijamin level minimum. Karena semua jalur lebih pendek pasti sudah dieksplor lebih dulu (Queue FIFO). DFS bisa nemu node duluan tapi mungkin lewat detour panjang.

⚠️ Jebakan umum di graph traversal:

🎯 Pilih BFS atau DFS:

🧪 Tebakan cepat: Friend-of-friend suggestion (2-degree away di social network). Pakai apa? BFS dengan distance limit 2. DFS bisa nyasar terlalu dalam, BFS pas memberhentikan di level 2.

TL;DR: BFS (queue, level-by-level, shortest unweighted path). DFS (stack/recursion, sedalam mungkin, natural cycle detection). Wajib visited set di graph. O(V+E) keduanya. Foundation hampir semua algoritma graph.

Yang akan kamu pelajari