티스토리 뷰
DFS란 (Depth-First Search)라고 해요. 해석하자면 깊이를 우선해서 탐색한다?라고 할 수 있습니다. 무조건 한 우물만 판다는 얘기라고 생각할 수 있습니다.
천천히 한번 봐볼게요.
일단 이런 그래프가 있다고 가정하겠습니다. 모든 간선은 양방향입니다.
이 그래프를 DFS를 적용해서 탐색하는 순서는 작은 숫자를 먼저 탐색한다 하면 결과는 (1->2->3->4->5->4->6->4->3->2->1)입니다.
그림으로 순서를 보겠습니다.
먼저 1에 방문합니다. 그다음 1은 방문했다고 체크해둡니다. 1에서 갈 수 있는 곳은 2와 5입니다. 작은 수 먼저 탐색하기로 하였으니 다음은 2로 이동합니다.
2에 방문합니다. 2는 방문했다고 체크해두고, 2에서 갈 수 있는 곳은 1, 3, 4, 5인데요, 1은 아까 방문했으니 3, 4, 5중에 작은 3에 방문합니다.
3에 방문합니다. 3에 방문했다고 체크해두고, 3에서는 2, 4에 갈 수 있네요. 하지만 2에 이미 방문했으니 4로 갑니다!
4에 방문합니다. 4를 방문했다고 체크하고, 4에서는 2, 3, 5, 6을 갈 수 있네요. 2, 3은 이미 방문했으니 5, 6중에 작은 수인 5로 갑니다.
5에 방문합니다. 5에서는 1, 2, 4에 갈 수 있네요. 하지만 1, 2, 4모두 이미 방문했던 곳이므로 5 이전에 있었던 곳(4)으로 갑니다. 여기서 5에서 탐색은 끝난거죠.
다시 4로 와서, 아까 4에서는 2, 3, 5, 6을 갈 수 있었죠? 2, 3은 방문 했었기 때문에 못갔고 5는 탐색이 끝났으니 남은 6에 가야겠네요!
6에 방문하고, 방문했다고 체크해둡니다. 6에서는 4에 갈 수 있지만 이미 방문했으니 6에서도 탐색은 끝난겁니다! 따라서 전에 있던 곳(4)로 갑니다.
4로 돌아와서, 4에서는 2, 3, 5, 6에 갈 수 있었는데 2, 3은 이미 방문했고, 5, 6은 탐색이 끝났군요. 따라서 이전에 있던 곳(3)으로 갑니다. 여기서도 4에서의 탐색은 끝!!!
3으로 돌아와서, 아까 3에서는 2, 4에 갈 수 있었는데 2는 이미 방문했고, 4는 탐색이 끝났네요. 그렇다면 이전에 있던 곳(2)으로 갑니다. 3에서의 탐색은 끝.
2로 돌아와서, 아까 2에서는 1, 3, 4, 5에 갈 수 있었는데 1은 이미 방문했고, 3, 4, 5는 탐색이 끝났으니 여기서도 원래 있던 곳(1)으로 가야겠네요. 2에서의 탐색은 끝!
1로 돌아왔습니다. 1에서는 2, 5에 갈 수 있었는데, 두곳 모두 탐색이 끝났네요! 그리고 이전에 있던곳도 없으므로 탐색 종료!!
깊이 우선 탐색 끝!!
그림을 보면 탐색 도중에 탐색이 끝났으면 이전 곳으로 돌아가는 Backtracking이 발생합니다. 이것이 발생하면, 그곳에서는 탐색이 끝났다고 볼 수 있습니다.
이것을 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 | #include <stdio.h> #include <stdbool.h> #define MAX 1001 int Graph[MAX][MAX]; bool visited[MAX]; int N, M; void dfs(int k) { visited[k] = true; for (int i = 1; i <= N; i++) { if (visited[i] != false || Graph[k][i] == 0) continue; dfs(i); } } int main(void) { scanf("%d%d", &N,&M); for (int i = 0; i < M; i++) { int u, v; scanf("%d%d", &u, &v); Graph[u][v] = 1; Graph[v][u] = 1; } for (int i = 1; i <= N; i++) { if (!visited[i]) { dfs(i); } } return 0; } | cs |
이렇게 나타낼 수 있습니다. N은 정점 갯수(갈 수 있는곳 갯수) M은 간선 갯수(정점과 정점을 이어주는)입니다.
9:dfs함수는 정점을 주면 그정점에서 갈 수 있는 곳을 깊이 우선으로 탐색하는 함수입니다.
10:정점 k를 방문 했다고 체크합니다.
11:정점최대 갯수만큼 탐색을 해야겠죠?
12:이미 방문했거나, 정점 k->i의 길이 없다면 다른 정점을 찾아봅니다.
13:12번째 줄에 의해 발견된 정점 i로 탐색을 시작합니다.
24~25:설명한 그래프가 양방향이라서 1->2도 되고 2->1도 될 수 있게 했습니다 25번줄을 지우면 단방향 그래프가 되겠네요.
'Coding > Algorithm' 카테고리의 다른 글
최적화 문제 동적 계획법 레시피(종만북) (0) | 2020.03.31 |
---|---|
What i learned!!! (2) | 2020.03.09 |
Tail Call Recursion (0) | 2019.02.19 |
정렬 간단한 정리 (0) | 2018.10.24 |
Quick Sorting(퀵 정렬) (0) | 2018.04.08 |