08 - Depth-First Search (DFS)
Depth-First Search (DFS)
๐ถ Materi 8
Depth-First Search (DFS) Kelompok 8
- Bismillah Ghaniyyu Putra Darmin
- Maynova Christin Gabryela Simamora
- Nabila Salsabila
- Moh. Ichwanul Muslimin Mayang
๐ Deskripsi Singkat
Depth-First Search (DFS) adalah algoritma pencarian atau penelusuran pada struktur data graf atau pohon yang bekerja dengan menjelajahi satu cabang sedalam mungkin sebelum mundur (backtrack) dan melanjutkan ke cabang berikutnya.
๐ง Konsep Utama
- Masukkan simpul (node) akar ke dalam stack
- Ambil node dari stack teratas, lalu cek apakah node tersebut merupakan solusi
- Jika node merupakan solusi, pencarian selesai dan hasil dikembalikan
- Jika node bukan solusi, masukkan seluruh node anak ke dalam stack
- Jika stack kosong, dan setiap node sudah dicek, pencarian berakhir
- Jika stack tidak kosong, ulangi pencarian mulai dari langkah ke-2
๐งโ๐ป Konsep Backtracking dalam Depth-First Search (DFS)
Depth-First Search (DFS) menggunakan strategi eksplorasi sedalam mungkin sebelum mundur (backtrack) ke node sebelumnya jika menemui jalan buntu. Dalam DFS, konsep backtracking muncul secara alami, terutama saat digunakan untuk menyelesaikan masalah pencarian jalur, kombinatorial, atau eksplorasi ruang solusi (seperti Sudoku, N-Queens, dan Rat in a Maze).
DFS bekerja dengan struktur stack, baik eksplisit (menggunakan struktur data stack) atau implisit melalui rekursi. Ketika DFS mencapai node tanpa jalur ke depan, ia akan mundur ke node sebelumnya โ inilah inti backtracking.
๐ฅ Input
- Representasi graf, bisa berupa:
- Matriks adjacency (graf kecil)
- Daftar adjacency (graf besar dan sparse)
- Matriks 2D seperti maze (untuk kasus seperti pencarian jalur)
- Titik awal (source node)
- Titik tujuan (jika ingin menemukan jalur dari source ke target)
๐ค Output
- Urutan simpul yang dikunjungi selama DFS
- Jalur dari simpul awal ke tujuan (jika diminta)
- Status pencapaian (apakah tujuan ditemukan)
๐งฎ Langkah Penyelesaian
- Mulai dari node awal (start node)
- Tandai node sebagai dikunjungi
- Lihat semua tetangga dari node
- Untuk setiap tetangga:
- Jika belum dikunjungi, lakukan DFS secara rekursif ke sana
- Jika buntu (semua tetangga sudah dikunjungi/tidak bisa diakses), kembali ke node sebelumnya (backtrack)
- Berhenti jika semua node telah dieksplorasi atau tujuan tercapai
๐งฉ Problem and Solution Example
Contoh maze (4x4):
1 1 0 1
0 1 0 1
1 1 1 1
0 0 1 1
Start: (0,0) Goal : (3,3)
Langkah Solusi
- Masuk ke (0,0)
- Coba ke kanan (0,1) โ
- Coba ke bawah (1,1) โ
- Coba ke bawah (2,1) โ
- Coba ke kanan (2,2) โ
- Coba ke kanan (2,3) โ
- Coba ke bawah (3,3) โ โ tujuan tercapai
Jalur DFS: (0,0) โ (0,1) โ (1,1) โ (2,1) โ (2,2) โ (2,3) โ (3,3) Representasi arah: RDRRDD
๐ป Contoh Kode (C++)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <vector>
using namespace std;
const int N = 4;
int maze[N][N] = {
{1, 1, 0, 1},
{0, 1, 0, 1},
{1, 1, 1, 1},
{0, 0, 1, 1}
};
bool visited[N][N]; // Penanda sel yang sudah dikunjungi
vector<pair<int, int>> path; // Menyimpan jalur menuju tujuan
// Arah gerak: kanan, bawah, kiri, atas
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
// Cek apakah posisi valid
bool isSafe(int x, int y) {
return (x >= 0 && x < N && y >= 0 && y < N &&
maze[x][y] == 1 && !visited[x][y]);
}
bool dfs(int x, int y) {
// Tandai sel sekarang sebagai dikunjungi
visited[x][y] = true;
path.push_back({x, y});
// Jika mencapai tujuan
if (x == N - 1 && y == N - 1)
return true;
// Coba ke 4 arah
for (int i = 0; i < 4; i++) {
int nextX = x + dx[i];
int nextY = y + dy[i];
if (isSafe(nextX, nextY)) {
if (dfs(nextX, nextY))
return true;
}
}
// Backtrack jika buntu
path.pop_back();
return false;
}
int main() {
memset(visited, false, sizeof(visited));
if (dfs(0, 0)) {
cout << "Jalur ditemukan:\n";
for (auto p : path)
cout << "(" << p.first << ", " << p.second << ") ";
cout << endl;
} else {
cout << "Tidak ada jalur yang tersedia.\n";
}
return 0;
}
๐ Analisis Kompleksitas
Kompleksitas Waktu
- DFS menjelajahi semua node dan edge
- Untuk graf dengan V simpul dan E sisi:
- O(V + E)
- Untuk grid N x N (seperti maze), worst case:
- O(Nยฒ) โ menjelajahi semua sel yang bisa dikunjungi
Kompleksitas Ruang
- Menggunakan stack (eksplisit atau rekursif): O(V)
- Visited array: O(V)
- Untuk maze/grid N x N:
- O(Nยฒ)
๐ Aplikasi Dunia Nyata
- Pencarian jalur di game dan labirin
- Penyusunan urutan (Topological Sort)
- Deteksi siklus dalam graf
- Pemecahan teka-teki (Sudoku, puzzle)
- Kompresi data (misalnya saat traversal pohon Huffman)
๐ช Kekuatan dan Keterbatasan
Kekuatan
- Penggunaan memori lebih efisien
- Mudah diimplementasikan
- Cocok untuk menemukan solusi kedalaman maksimal
- Digunakan dalam banyak algoritma penting
Keterbatasan
- Tidak menjamin solusi terbaik
- Bisa masuk ke infinite loop (pada graf siklik)
- Kurang efisien di graf luas tapi dangkal
- Tidak cocok untuk semua masalah
๐ Kesimpulan
Depth-First Search (DFS) adalah algoritma penelusuran graf atau grid yang mengeksplorasi simpul sedalam mungkin sebelum kembali ke simpul sebelumnya. DFS secara alami menerapkan konsep backtracking, sangat cocok untuk menyelesaikan masalah pencarian jalur dan kombinatorial. Efisien digunakan dalam banyak skenario seperti maze solving, deteksi siklus, hingga logika permainan dan AI.